LCOV - code coverage report
Current view: top level - src/ui/client/helpers/user_update_helper - user_update_helper.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 141 156 90.4 %
Date: 2020-12-04 18:41:24 Functions: 0 0 -

          Line data    Source code
       1             : import 'package:cached_network_image/cached_network_image.dart';
       2             : import 'package:flutter/material.dart';
       3             : import 'package:flutter/services.dart';
       4             : import 'package:google_fonts/google_fonts.dart';
       5             : import 'package:mvvm_builder/mvvm_builder.dart';
       6             : import 'package:pal/src/injectors/user_app/user_app_injector.dart';
       7             : import 'package:pal/src/services/package_version.dart';
       8             : import 'package:pal/src/theme.dart';
       9             : import 'package:pal/src/ui/client/helpers/user_update_helper/user_update_helper_presenter.dart';
      10             : import 'package:pal/src/ui/client/helpers/user_update_helper/user_update_helper_viewmodel.dart';
      11             : import 'package:pal/src/ui/client/helpers/user_update_helper/widgets/animated_progress_bar.dart';
      12             : import 'package:pal/src/ui/client/helpers/user_update_helper/widgets/release_note_cell.dart';
      13             : import 'package:pal/src/ui/client/widgets/animated/animated_scale.dart';
      14             : import 'package:pal/src/ui/client/widgets/animated/animated_translate.dart';
      15             : import 'package:pal/src/ui/shared/helper_shared_viewmodels.dart';
      16             : 
      17             : abstract class UserUpdateHelperView {
      18             :   void playAnimation(
      19             :     MvvmContext context,
      20             :     bool isReversed,
      21             :     int index,
      22             :     Function callback,
      23             :   );
      24             :   void onThanksButtonCallback();
      25             : }
      26             : 
      27             : class UserUpdateHelperPage extends StatelessWidget
      28             :     implements UserUpdateHelperView {
      29             :   final HelperBoxViewModel helperBoxViewModel;
      30             :   final HelperTextViewModel titleLabel;
      31             :   final List<HelperTextViewModel> changelogLabels;
      32             :   final HelperTextViewModel thanksButtonLabel;
      33             :   final PackageVersionReader packageVersionReader;
      34             :   final HelperImageViewModel helperImageViewModel;
      35             :   final Function onPositivButtonTap;
      36             : 
      37           1 :   UserUpdateHelperPage({
      38             :     Key key,
      39             :     @required this.helperBoxViewModel,
      40             :     @required this.titleLabel,
      41             :     @required this.changelogLabels,
      42             :     @required this.onPositivButtonTap,
      43             :     this.helperImageViewModel,
      44             :     this.thanksButtonLabel,
      45             :     this.packageVersionReader,
      46           0 :   })  : assert(helperBoxViewModel != null),
      47           0 :         assert(titleLabel != null),
      48           0 :         assert(changelogLabels != null);
      49             : 
      50             :   final _mvvmPageBuilder =
      51             :       MVVMPageBuilder<UserUpdateHelperPresenter, UserUpdateHelperModel>();
      52             : 
      53           1 :   @override
      54             :   Widget build(BuildContext context) {
      55           2 :     return _mvvmPageBuilder.build(
      56           1 :       key: UniqueKey(),
      57             :       context: context,
      58           1 :       multipleAnimControllerBuilder: (tickerProvider) {
      59           1 :         return [
      60             :           // Changelog
      61           1 :           AnimationController(
      62             :             vsync: tickerProvider,
      63           1 :             duration: Duration(
      64             :               milliseconds: 1100,
      65             :             ),
      66             :           ),
      67             :           // Progress bar
      68           1 :           AnimationController(
      69             :             vsync: tickerProvider,
      70           1 :             duration: Duration(
      71             :               milliseconds: 5000,
      72             :             ),
      73             :           ),
      74             :           // Image logo
      75           1 :           AnimationController(
      76             :             vsync: tickerProvider,
      77           1 :             duration: Duration(
      78             :               milliseconds: 700,
      79             :             ),
      80             :           ),
      81             :           // Title
      82           1 :           AnimationController(
      83             :             vsync: tickerProvider,
      84           1 :             duration: Duration(
      85             :               milliseconds: 700,
      86             :             ),
      87             :           ),
      88             :         ];
      89             :       },
      90           1 :       animListener: (context, presenter, model) {
      91           1 :         if (model.changelogCascadeAnimation) {
      92           1 :           this.playAnimation(
      93             :             context,
      94           1 :             model.isReversedAnimations,
      95             :             0,
      96           1 :             presenter.onCascadeAnimationEnd,
      97             :           );
      98             :         }
      99           1 :         if (model.progressBarAnimation) {
     100           1 :           this.playAnimation(
     101             :             context,
     102           1 :             model.isReversedAnimations,
     103             :             1,
     104           1 :             presenter.onProgressBarAnimationEnd,
     105             :           );
     106             :         }
     107           1 :         if (model.imageAnimation) {
     108           1 :           this.playAnimation(
     109             :             context,
     110           1 :             model.isReversedAnimations,
     111             :             2,
     112           1 :             presenter.onImageAnimationEnd,
     113             :           );
     114             :         }
     115           1 :         if (model.titleAnimation) {
     116           1 :           this.playAnimation(
     117             :             context,
     118           1 :             model.isReversedAnimations,
     119             :             3,
     120           1 :             presenter.onTitleAnimationEnd,
     121             :           );
     122             :         }
     123             :       },
     124           2 :       presenterBuilder: (context) => UserUpdateHelperPresenter(
     125             :         this,
     126           1 :         packageVersionReader ?? UserInjector.of(context).packageVersionReader,
     127             :       ),
     128           1 :       builder: (context, presenter, model) {
     129           1 :         return this._buildPage(context, presenter, model);
     130             :       },
     131             :     );
     132             :   }
     133             : 
     134           1 :   Widget _buildPage(
     135             :     final MvvmContext context,
     136             :     final UserUpdateHelperPresenter presenter,
     137             :     final UserUpdateHelperModel model,
     138             :   ) {
     139           1 :     return AnimatedOpacity(
     140           1 :       duration: Duration(milliseconds: 500),
     141             :       curve: Curves.fastOutSlowIn,
     142           1 :       opacity: model.helperOpacity,
     143           1 :       child: Scaffold(
     144           1 :         key: ValueKey('pal_UserUpdateHelperWidget_Scaffold'),
     145           2 :         backgroundColor: helperBoxViewModel?.backgroundColor,
     146           1 :         body: SafeArea(
     147           1 :           child: Container(
     148             :             width: double.infinity,
     149           1 :             child: Container(
     150           1 :               child: Column(
     151           1 :                 children: [
     152           6 :                   if (helperImageViewModel?.url != null && helperImageViewModel.url.length > 0)
     153           1 :                     Flexible(
     154           1 :                       key: ValueKey('pal_UserUpdateHelperWidget_Icon'),
     155             :                       flex: 4,
     156           1 :                       child: _buildMedia(context),
     157             :                     ),
     158           1 :                   Flexible(
     159           1 :                     key: ValueKey('pal_UserUpdateHelperWidget_AppSummary'),
     160             :                     flex: 2,
     161           1 :                     child: _buildAppSummary(context, model),
     162             :                   ),
     163           1 :                   Expanded(
     164           1 :                     key: ValueKey('pal_UserUpdateHelperWidget_ReleaseNotes'),
     165             :                     flex: 5,
     166           1 :                     child: _buildReleaseNotes(context, model),
     167             :                   ),
     168           1 :                   _buildThanksButton(context, model, presenter),
     169             :                 ],
     170             :               ),
     171             :             ),
     172             :           ),
     173             :         ),
     174             :       ),
     175             :     );
     176             :   }
     177             : 
     178           1 :   Widget _buildMedia(
     179             :     final MvvmContext context,
     180             :   ) {
     181           1 :     return Container(
     182             :       width: double.infinity,
     183           1 :       child: Padding(
     184             :         padding: const EdgeInsets.all(25.0),
     185           1 :         child: AnimatedScaleWidget(
     186           1 :           widget: ClipRRect(
     187           1 :             borderRadius: BorderRadius.circular(15.0),
     188           1 :             child: CachedNetworkImage(
     189           1 :               key: ValueKey('pal_UserUpdateHelperWidget_Image'),
     190           2 :               imageUrl: helperImageViewModel?.url,
     191             :               fit: BoxFit.contain,
     192           1 :               placeholder: (context, url) =>
     193           2 :                   Center(child: CircularProgressIndicator()),
     194           0 :               errorWidget: (BuildContext context, String url, dynamic error) {
     195           0 :                 return Image.asset(
     196             :                   'packages/pal/assets/images/create_helper.png',
     197             :                 );
     198             :               },
     199             :             ),
     200             :           ),
     201           2 :           animationController: context.animationsControllers[2],
     202             :         ),
     203             :       ),
     204             :     );
     205             :   }
     206             : 
     207           1 :   Container _buildAppSummary(
     208             :     final MvvmContext context,
     209             :     final UserUpdateHelperModel model,
     210             :   ) {
     211           1 :     return Container(
     212             :       width: double.infinity,
     213           1 :       child: AnimatedTranslateWidget(
     214           4 :         position: Tween<Offset>(begin: Offset(-1.0, 0.0), end: Offset(0, 0)),
     215           2 :         animationController: context.animationsControllers[3],
     216           1 :         widget: Column(
     217             :           mainAxisAlignment: MainAxisAlignment.center,
     218           1 :           children: [
     219           1 :             Text(
     220           2 :               titleLabel?.text ?? 'New application update',
     221           1 :               key: ValueKey('pal_UserUpdateHelperWidget_AppSummary_Title'),
     222           1 :               style: TextStyle(
     223           2 :                 fontSize: titleLabel?.fontSize ?? 27.0,
     224           2 :                 fontWeight: titleLabel?.fontWeight ?? FontWeight.normal,
     225           2 :                 color: titleLabel?.fontColor ??
     226           0 :                     PalTheme.of(context.buildContext).colors.light,
     227           1 :               ).merge(
     228           3 :                 GoogleFonts.getFont(titleLabel?.fontFamily ?? 'Montserrat'),
     229             :               ),
     230             :             ),
     231           1 :             SizedBox(
     232             :               height: 10.0,
     233             :             ),
     234           1 :             Text(
     235           2 :               'Version ${model.appVersion ?? '1.0.0'}',
     236           1 :               key: ValueKey('pal_UserUpdateHelperWidget_AppSummary_Version'),
     237           1 :               style: TextStyle(
     238             :                 fontSize: 13.0,
     239             :                 fontWeight: FontWeight.bold,
     240             :                 color: Colors.white,
     241             :               ),
     242             :             ),
     243             :           ],
     244             :         ),
     245             :       ),
     246             :     );
     247             :   }
     248             : 
     249           1 :   SizedBox _buildThanksButton(
     250             :     final MvvmContext context,
     251             :     final UserUpdateHelperModel model,
     252             :     final UserUpdateHelperPresenter presenter,
     253             :   ) {
     254           1 :     return SizedBox(
     255           1 :       key: ValueKey('pal_UserUpdateHelperWidget_ThanksButton'),
     256             :       width: double.infinity,
     257           1 :       child: Padding(
     258             :         padding: const EdgeInsets.only(
     259             :           left: 20.0,
     260             :           right: 20.0,
     261             :           bottom: 15.0,
     262             :         ),
     263           1 :         child: RaisedButton(
     264           1 :           key: ValueKey('pal_UserUpdateHelperWidget_ThanksButton_Raised'),
     265           4 :           color: PalTheme.of(context.buildContext).colors.dark,
     266           1 :           onPressed: model.showThanksButton
     267           0 :               ? () {
     268           0 :                   HapticFeedback.selectionClick();
     269           0 :                   presenter.onThanksButtonCallback();
     270             :                 }
     271             :               : null,
     272           1 :           shape: RoundedRectangleBorder(
     273           1 :             borderRadius: BorderRadius.circular(8.0),
     274             :           ),
     275           1 :           child: AnimatedSwitcher(
     276           1 :             duration: Duration(milliseconds: 300),
     277           1 :             transitionBuilder: (Widget child, Animation<double> animation) =>
     278           1 :                 ScaleTransition(
     279             :               child: child,
     280             :               scale: animation,
     281             :             ),
     282           1 :             child: model.showThanksButton
     283           1 :                 ? Padding(
     284             :                     padding: const EdgeInsets.symmetric(vertical: 12.0),
     285           1 :                     child: Text(
     286           2 :                       thanksButtonLabel?.text ?? 'Thank you !',
     287           1 :                       style: TextStyle(
     288           2 :                         fontSize: thanksButtonLabel?.fontSize ?? 18.0,
     289           2 :                         color: thanksButtonLabel?.fontColor ?? Colors.white,
     290             :                         fontWeight:
     291           2 :                             thanksButtonLabel?.fontWeight ?? FontWeight.normal,
     292           1 :                       ).merge(
     293           1 :                         GoogleFonts.getFont(
     294           2 :                             titleLabel?.fontFamily ?? 'Montserrat'),
     295             :                       ),
     296             :                     ),
     297             :                   )
     298           1 :                 : AnimatedProgressBar(
     299           2 :                     animationController: context.animationsControllers[1],
     300             :                   ),
     301             :           ),
     302             :         ),
     303             :       ),
     304             :     );
     305             :   }
     306             : 
     307           1 :   SingleChildScrollView _buildReleaseNotes(
     308             :     final MvvmContext context,
     309             :     final UserUpdateHelperModel model,
     310             :   ) {
     311           1 :     return SingleChildScrollView(
     312           1 :       child: Container(
     313             :         width: double.infinity,
     314           1 :         child: Padding(
     315             :           padding: const EdgeInsets.symmetric(horizontal: 27.0),
     316           1 :           child: Column(
     317           1 :             key: ValueKey('pal_UserUpdateHelperWidget_ReleaseNotes_List'),
     318           1 :             children: _buildReleaseNotesLabels(context, model),
     319             :           ),
     320             :         ),
     321             :       ),
     322             :     );
     323             :   }
     324             : 
     325           1 :   List<Widget> _buildReleaseNotesLabels(
     326             :     final MvvmContext context,
     327             :     final UserUpdateHelperModel model,
     328             :   ) {
     329           1 :     List<Widget> labels = [];
     330             :     int index = 0;
     331           2 :     for (HelperTextViewModel label in changelogLabels) {
     332           3 :       var stepTime = 1.0 / changelogLabels.length;
     333           1 :       var animationStart = stepTime * index;
     334           1 :       var animationEnd = stepTime + animationStart;
     335             : 
     336           1 :       labels.add(
     337           1 :         ReleaseNoteCell(
     338           1 :           index: index++,
     339             :           customLabel: label,
     340           2 :           animationController: context.animationsControllers[0],
     341           1 :           positionCurve: Interval(
     342             :             animationStart,
     343             :             animationEnd,
     344             :             curve: Curves.decelerate,
     345             :           ),
     346           1 :           opacityCurve: Interval(
     347             :             animationStart,
     348             :             animationEnd,
     349             :             curve: Curves.decelerate,
     350             :           ),
     351             :         ),
     352             :       );
     353             :     }
     354             :     return labels;
     355             :   }
     356             : 
     357           1 :   @override
     358             :   void playAnimation(
     359             :     MvvmContext context,
     360             :     bool isReversed,
     361             :     int index,
     362             :     Function callback,
     363             :   ) {
     364             :     if (isReversed) {
     365           0 :       context.animationsControllers[index]
     366           0 :           .reverse()
     367           0 :           .then((value) => callback());
     368             :     } else {
     369           2 :       context.animationsControllers[index]
     370           1 :           .forward()
     371           3 :           .then((value) => callback());
     372             :     }
     373             :   }
     374             : 
     375           0 :   @override
     376             :   void onThanksButtonCallback() {
     377           0 :     if (this.onPositivButtonTap != null) {
     378           0 :       this.onPositivButtonTap();
     379             :     }
     380             :   }
     381             : }

Generated by: LCOV version 1.14