Skip to content

Commit

Permalink
Add get started step to tutorial
Browse files Browse the repository at this point in the history
  • Loading branch information
ferndot committed Mar 21, 2020
1 parent e4eca5a commit 20cd65c
Show file tree
Hide file tree
Showing 7 changed files with 214 additions and 81 deletions.
19 changes: 11 additions & 8 deletions lib/src/data/models/preferences.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,32 @@ part 'preferences.g.dart';
@JsonSerializable()
class Preferences {
final String userId;
final bool completedTutorial;
final bool agreedToTerms;
final Assessment lastAssessment;
final bool isFirstLoad;
final bool consented;

Preferences({
userId,
completedTutorial,
this.agreedToTerms,
this.lastAssessment,
isFirstLoad,
consented,
}) : userId = userId ??
}) : completedTutorial = completedTutorial ?? false,
userId = userId ??
Uuid().v4(
options: {
'grng': UuidUtil.cryptoRNG,
},
),
isFirstLoad = isFirstLoad ?? true,
consented = consented ?? false;
);

Preferences cloneWith({
bool completedTutorial,
bool agreedToTerms,
Assessment lastAssessment,
}) {
return Preferences(
userId: this.userId,
completedTutorial: completedTutorial ?? this.completedTutorial,
agreedToTerms: agreedToTerms ?? this.agreedToTerms,
lastAssessment: lastAssessment ?? this.lastAssessment,
);
}
Expand Down
8 changes: 4 additions & 4 deletions lib/src/data/models/preferences.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/src/ui/router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ var appRoutes = {
};

String getInitialRoute(PreferencesState preferencesState) {
if (preferencesState.preferences.isFirstLoad) {
if (!preferencesState.preferences.completedTutorial) {
return TutorialScreen.routeName;
} else {
return HomeScreen.routeName;
Expand Down
158 changes: 107 additions & 51 deletions lib/src/ui/screens/tutorial/steps/consent.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,70 +2,126 @@ import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:provider/provider.dart';

import 'package:coronavirus_diary/src/blocs/preferences/preferences.dart';
import 'package:coronavirus_diary/src/ui/widgets/loading_indicator.dart';

class ConsentStep extends StatelessWidget {
void _handleResponse(
{BuildContext context, PreferencesState state, bool response}) {
// Save response
Preferences newPreferences = state.preferences.cloneWith(
agreedToTerms: response,
);
context.bloc<PreferencesBloc>().add(UpdatePreferences(newPreferences));

// Navigate to next page
Provider.of<PageController>(context, listen: false).nextPage(
duration: Duration(milliseconds: 400),
curve: Curves.easeInOut,
);
}

@override
Widget build(BuildContext context) {
return SafeArea(
child: FutureBuilder(
future: rootBundle.loadString('assets/copy/consent.md'),
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
if (snapshot.hasData) {
return Stack(
children: <Widget>[
Markdown(
padding: EdgeInsets.fromLTRB(20, 40, 20, 100),
data: snapshot.data,
styleSheet:
MarkdownStyleSheet.fromTheme(Theme.of(context)).copyWith(
blockSpacing: 20,
h1Align: WrapAlignment.center,
p: TextStyle(fontSize: 18),
),
),
Align(
alignment: Alignment.bottomCenter,
child: DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
colors: <Color>[
Theme.of(context).primaryColor,
Theme.of(context).primaryColor.withOpacity(0.6),
Theme.of(context).primaryColor.withOpacity(0),
],
stops: <double>[0, 0.8, 1.0],
return BlocBuilder<PreferencesBloc, PreferencesState>(
builder: (context, state) {
final bool agreed = state.preferences.agreedToTerms != null &&
state.preferences.agreedToTerms;
final bool rejected = state.preferences.agreedToTerms != null &&
!state.preferences.agreedToTerms;

return SafeArea(
child: FutureBuilder(
future: rootBundle.loadString('assets/copy/consent.md'),
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
if (snapshot.hasData) {
return Stack(
children: <Widget>[
Markdown(
padding: EdgeInsets.fromLTRB(20, 40, 20, 100),
data: snapshot.data,
styleSheet:
MarkdownStyleSheet.fromTheme(Theme.of(context))
.copyWith(
blockSpacing: 20,
h1Align: WrapAlignment.center,
p: TextStyle(fontSize: 18),
),
),
child: Padding(
padding: EdgeInsets.fromLTRB(20, 40, 20, 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
RaisedButton(
onPressed: () => {},
child: Text('No'),
Align(
alignment: Alignment.bottomCenter,
child: DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
colors: <Color>[
Theme.of(context).primaryColor,
Theme.of(context).primaryColor.withOpacity(0.6),
Theme.of(context).primaryColor.withOpacity(0),
],
stops: <double>[0, 0.8, 1.0],
),
RaisedButton(
onPressed: () => {},
child: Text('I agree'),
),
child: Padding(
padding: EdgeInsets.fromLTRB(20, 40, 20, 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
RaisedButton(
onPressed: () => _handleResponse(
context: context,
state: state,
response: false,
),
child: rejected
? Row(
children: <Widget>[
Icon(
Icons.close,
color: Colors.red,
),
Text('Did not agree'),
],
)
: Text('No'),
),
RaisedButton(
onPressed: () => _handleResponse(
context: context,
state: state,
response: true,
),
child: agreed
? Row(
children: <Widget>[
Icon(
Icons.check,
color: Colors.green,
),
Text('Agreed'),
],
)
: Text('I agree'),
),
],
),
],
),
),
),
),
),
],
);
} else {
return LoadingIndicator('Loading...');
}
},
),
],
);
} else {
return LoadingIndicator('Loading...');
}
},
),
);
},
);
}
}
69 changes: 69 additions & 0 deletions lib/src/ui/screens/tutorial/steps/get_started.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';

import 'package:coronavirus_diary/src/blocs/preferences/preferences.dart';
import 'package:coronavirus_diary/src/ui/router.dart';

class GetStartedStep extends StatelessWidget {
void _completeTutorial(BuildContext context, PreferencesState state) {
// Save response
Preferences newPreferences = state.preferences.cloneWith(
completedTutorial: true,
);
context.bloc<PreferencesBloc>().add(UpdatePreferences(newPreferences));

// Navigate to home page and put it at the
// bottom of the navigation stack
Navigator.pushNamedAndRemoveUntil(
context,
HomeScreen.routeName,
(Route<dynamic> route) => false,
);
}

@override
Widget build(BuildContext context) {
return BlocBuilder<PreferencesBloc, PreferencesState>(
builder: (context, state) {
return SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
width: double.infinity,
color: Colors.white.withOpacity(0.2),
padding: EdgeInsets.symmetric(horizontal: 40, vertical: 20),
margin: EdgeInsets.only(bottom: 20),
child: Center(
child: FaIcon(
FontAwesomeIcons.handsHelping,
color: Colors.white,
size: 80,
),
),
),
Container(
padding: EdgeInsets.symmetric(horizontal: 40),
margin: EdgeInsets.only(bottom: 50),
child: Text(
"You've joined the Coronavirus Diary community!",
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.title,
),
),
Container(
padding: EdgeInsets.symmetric(horizontal: 40),
margin: EdgeInsets.only(bottom: 40),
child: RaisedButton(
onPressed: () => _completeTutorial(context, state),
child: Text('Click here to get started'),
),
),
],
),
);
},
);
}
}
12 changes: 3 additions & 9 deletions lib/src/ui/screens/tutorial/steps/index.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
import 'package:flutter/material.dart';

import 'consent.dart';
import 'intro.dart';

final List<Widget> steps = [
IntroStep(),
ConsentStep(),
];
export 'consent.dart';
export 'get_started.dart';
export 'intro.dart';
27 changes: 19 additions & 8 deletions lib/src/ui/screens/tutorial/tutorial.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:provider/provider.dart';

import 'package:coronavirus_diary/src/blocs/preferences/preferences.dart';
import 'steps/index.dart';

class TutorialScreen extends StatefulWidget {
Expand All @@ -26,14 +29,22 @@ class _TutorialScreenState extends State<TutorialScreen> {

@override
Widget build(BuildContext context) {
return Scaffold(
body: PageView.builder(
controller: _pageController,
itemCount: steps.length,
itemBuilder: (BuildContext context, int index) {
return steps[index];
},
),
return BlocBuilder<PreferencesBloc, PreferencesState>(
builder: (context, state) {
return Scaffold(
body: ChangeNotifierProvider(
create: (context) => _pageController,
child: PageView(
controller: _pageController,
children: <Widget>[
IntroStep(),
ConsentStep(),
if (state.preferences.agreedToTerms == true) GetStartedStep(),
],
),
),
);
},
);
}
}

0 comments on commit 20cd65c

Please sign in to comment.