2019-03-09 20:34:09 -06:00
|
|
|
import 'package:flutter/material.dart';
|
2019-03-21 00:06:56 -06:00
|
|
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
2019-03-09 20:34:09 -06:00
|
|
|
|
2019-03-11 23:55:02 -06:00
|
|
|
import '../models/task_model.dart';
|
2019-03-13 21:51:42 -06:00
|
|
|
import '../blocs/home_bloc.dart';
|
2019-03-20 22:57:44 -06:00
|
|
|
import '../widgets/home_app_bar.dart';
|
2019-03-31 00:53:57 -06:00
|
|
|
import '../widgets/new_item_dialog_route.dart';
|
2019-03-11 23:38:00 -06:00
|
|
|
import '../widgets/task_list_tile.dart';
|
2019-03-12 21:23:35 -06:00
|
|
|
import '../widgets/loading_indicator.dart';
|
2019-04-15 20:27:42 -05:00
|
|
|
import '../widgets/populated_drawer.dart';
|
2019-03-30 23:52:01 -06:00
|
|
|
import '../widgets/search-box.dart';
|
2019-03-09 21:47:04 -06:00
|
|
|
|
2019-03-13 21:51:42 -06:00
|
|
|
class HomeScreen extends StatefulWidget {
|
|
|
|
|
createState() => _HomeScreenState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class _HomeScreenState extends State<HomeScreen> {
|
2019-03-21 00:06:56 -06:00
|
|
|
static const _searchBoxHeight = 50.0;
|
|
|
|
|
|
2019-04-05 15:03:04 -06:00
|
|
|
/// An instance of the bloc for this screen.
|
2019-03-13 21:51:42 -06:00
|
|
|
final HomeBloc bloc = HomeBloc();
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
initState() {
|
|
|
|
|
super.initState();
|
|
|
|
|
bloc.fetchTasks();
|
|
|
|
|
}
|
2019-03-09 21:47:04 -06:00
|
|
|
|
2019-03-09 20:34:09 -06:00
|
|
|
Widget build(BuildContext context) {
|
2019-03-31 00:26:33 -06:00
|
|
|
return StreamBuilder(
|
|
|
|
|
stream: bloc.userStream,
|
|
|
|
|
builder: (BuildContext context, AsyncSnapshot<FirebaseUser> userSnap) {
|
2019-04-15 20:33:05 -05:00
|
|
|
String userAvatarUrl, userDisplayName = '', userEmail = '';
|
2019-03-31 00:26:33 -06:00
|
|
|
|
|
|
|
|
if (userSnap.hasData) {
|
|
|
|
|
userAvatarUrl = userSnap.data.photoUrl;
|
|
|
|
|
userDisplayName = userSnap.data.displayName;
|
2019-04-15 20:27:42 -05:00
|
|
|
userEmail = userSnap.data.email;
|
2019-03-31 00:26:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Scaffold(
|
2019-04-15 20:27:42 -05:00
|
|
|
drawer: PopulatedDrawer(
|
|
|
|
|
userAvatarUrl: userAvatarUrl,
|
|
|
|
|
userDisplayName: userDisplayName,
|
|
|
|
|
userEmail: userEmail,
|
|
|
|
|
selectedScreen: Screen.home,
|
|
|
|
|
),
|
2019-03-31 00:26:33 -06:00
|
|
|
floatingActionButton: FloatingActionButton(
|
|
|
|
|
child: Icon(FontAwesomeIcons.plus),
|
|
|
|
|
backgroundColor: Color(0xFF707070),
|
|
|
|
|
onPressed: () => _showDialog(context),
|
|
|
|
|
),
|
|
|
|
|
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
|
|
|
|
|
appBar: HomeAppBar(
|
|
|
|
|
avatarUrl: userAvatarUrl,
|
|
|
|
|
subtitle: 'Hello $userDisplayName!',
|
|
|
|
|
),
|
|
|
|
|
body: StreamBuilder(
|
|
|
|
|
stream: bloc.userTasks,
|
|
|
|
|
builder:
|
|
|
|
|
(BuildContext context, AsyncSnapshot<List<TaskModel>> snap) {
|
|
|
|
|
if (!snap.hasData) {
|
|
|
|
|
return Center(
|
|
|
|
|
child: LoadingIndicator(),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
return Stack(
|
|
|
|
|
overflow: Overflow.visible,
|
|
|
|
|
children: <Widget>[
|
|
|
|
|
_buildTasksList(snap.data),
|
|
|
|
|
// This container is needed to make it seem like the search box is
|
|
|
|
|
// part of the app bar.
|
|
|
|
|
Container(
|
|
|
|
|
height: _searchBoxHeight / 2,
|
|
|
|
|
width: double.infinity,
|
|
|
|
|
color: Theme.of(context).cardColor,
|
|
|
|
|
),
|
|
|
|
|
SearchBox(
|
2019-04-05 19:26:24 -06:00
|
|
|
onChanged: bloc.updateSearchBoxText,
|
2019-03-31 00:26:33 -06:00
|
|
|
height: 50.0,
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
);
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
},
|
2019-03-09 20:34:09 -06:00
|
|
|
);
|
|
|
|
|
}
|
2019-03-13 21:51:42 -06:00
|
|
|
|
2019-03-30 23:06:47 -06:00
|
|
|
void _showDialog(BuildContext context) {
|
2019-03-30 23:52:01 -06:00
|
|
|
Navigator.of(context).push(NewItemDialogRoute());
|
2019-03-30 23:06:47 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Widget _buildTasksList(List<TaskModel> tasks) {
|
2019-03-27 15:52:16 -06:00
|
|
|
return ListView(
|
|
|
|
|
padding: EdgeInsets.only(top: _searchBoxHeight + 15),
|
|
|
|
|
children: tasks
|
|
|
|
|
.map((task) => Container(
|
|
|
|
|
child: TaskListTile(
|
|
|
|
|
task: task,
|
|
|
|
|
onDone: () => bloc.markTaskAsDone(task),
|
2019-04-06 20:38:37 -06:00
|
|
|
onEventPressed: () {
|
2019-04-06 22:53:22 -06:00
|
|
|
// Include the event name in the route.
|
|
|
|
|
Navigator.of(context).pushNamed('event/${task.event}');
|
2019-04-06 20:38:37 -06:00
|
|
|
},
|
|
|
|
|
onEditPressed: () {
|
2019-04-06 22:53:22 -06:00
|
|
|
// Include the id of the task to be edited in the route.
|
|
|
|
|
Navigator.of(context).pushNamed('editTask/${task.id}');
|
2019-04-05 00:28:15 -06:00
|
|
|
},
|
2019-03-27 15:52:16 -06:00
|
|
|
),
|
|
|
|
|
padding: EdgeInsets.only(bottom: 12),
|
|
|
|
|
))
|
2019-03-28 00:47:05 -06:00
|
|
|
.toList()
|
|
|
|
|
..add(Container(height: 70)),
|
2019-03-27 15:52:16 -06:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-13 21:51:42 -06:00
|
|
|
@override
|
|
|
|
|
void dispose() {
|
|
|
|
|
bloc.dispose();
|
|
|
|
|
super.dispose();
|
|
|
|
|
}
|
2019-03-09 20:34:09 -06:00
|
|
|
}
|