| 
									
										
										
										
											2020-05-21 20:25:25 +02:00
										 |  |  | import 'package:flutter/material.dart'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-23 13:22:33 +02:00
										 |  |  | import 'about_screen.dart'; | 
					
						
							| 
									
										
										
										
											2020-05-21 20:25:25 +02:00
										 |  |  | import 'backend.dart'; | 
					
						
							|  |  |  | import 'date_utils.dart'; | 
					
						
							| 
									
										
										
										
											2020-05-23 10:58:06 +02:00
										 |  |  | import 'localizations.dart'; | 
					
						
							| 
									
										
										
										
											2020-05-21 20:25:25 +02:00
										 |  |  | import 'memo.dart'; | 
					
						
							|  |  |  | import 'memo_editor.dart'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /// The Memor home screen.
 | 
					
						
							|  |  |  | ///
 | 
					
						
							|  |  |  | /// The screen shows nothing more than a list of scheduled memos. They can be
 | 
					
						
							|  |  |  | /// dismissed by swiping and edited by tapping.
 | 
					
						
							|  |  |  | class HomeScreen extends StatelessWidget { | 
					
						
							|  |  |  |   Future<Memo> _showMemoEditor(BuildContext context, [Memo memo]) async { | 
					
						
							|  |  |  |     return await Navigator.push( | 
					
						
							|  |  |  |       context, | 
					
						
							|  |  |  |       MaterialPageRoute( | 
					
						
							|  |  |  |         builder: (context) => MemoEditor( | 
					
						
							|  |  |  |           memo: memo, | 
					
						
							|  |  |  |         ), | 
					
						
							|  |  |  |         fullscreenDialog: true, | 
					
						
							|  |  |  |       ), | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   Widget build(BuildContext context) { | 
					
						
							|  |  |  |     final backend = MemorBackend.of(context); | 
					
						
							| 
									
										
										
										
											2020-05-23 10:58:06 +02:00
										 |  |  |     final l10n = MemorLocalizations.of(context); | 
					
						
							| 
									
										
										
										
											2020-05-21 20:25:25 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return Scaffold( | 
					
						
							|  |  |  |       appBar: AppBar( | 
					
						
							| 
									
										
										
										
											2020-05-23 10:58:06 +02:00
										 |  |  |         title: Text(l10n.title), | 
					
						
							| 
									
										
										
										
											2020-05-23 13:22:33 +02:00
										 |  |  |         actions: <Widget>[ | 
					
						
							|  |  |  |           PopupMenuButton( | 
					
						
							|  |  |  |             itemBuilder: (context) => [ | 
					
						
							|  |  |  |               PopupMenuItem( | 
					
						
							|  |  |  |                 value: 0, | 
					
						
							|  |  |  |                 child: Text(l10n.about), | 
					
						
							|  |  |  |               ), | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |             onSelected: (value) { | 
					
						
							|  |  |  |               if (value == 0) { | 
					
						
							|  |  |  |                 Navigator.push( | 
					
						
							|  |  |  |                   context, | 
					
						
							|  |  |  |                   MaterialPageRoute( | 
					
						
							|  |  |  |                     builder: (context) => AboutScreen(), | 
					
						
							|  |  |  |                   ), | 
					
						
							|  |  |  |                 ); | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |         ], | 
					
						
							| 
									
										
										
										
											2020-05-21 20:25:25 +02:00
										 |  |  |       ), | 
					
						
							|  |  |  |       body: backend.loading | 
					
						
							|  |  |  |           ? Center( | 
					
						
							|  |  |  |               child: CircularProgressIndicator(), | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |           : StreamBuilder<List<Memo>>( | 
					
						
							|  |  |  |               stream: backend.memos, | 
					
						
							|  |  |  |               builder: (context, snapshot) { | 
					
						
							| 
									
										
										
										
											2020-05-23 11:42:18 +02:00
										 |  |  |                 final scaffold = Scaffold.of(context); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-21 20:25:25 +02:00
										 |  |  |                 if (snapshot.hasData) { | 
					
						
							|  |  |  |                   final memos = snapshot.data; | 
					
						
							| 
									
										
										
										
											2020-05-23 10:58:59 +02:00
										 |  |  |                   final now = DateTime.now(); | 
					
						
							| 
									
										
										
										
											2020-05-21 20:25:25 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                   if (memos.isNotEmpty) { | 
					
						
							|  |  |  |                     return ListView.builder( | 
					
						
							|  |  |  |                       itemCount: memos.length, | 
					
						
							|  |  |  |                       itemBuilder: (context, index) { | 
					
						
							|  |  |  |                         final memo = memos[index]; | 
					
						
							|  |  |  |                         final scheduled = memo.scheduled; | 
					
						
							| 
									
										
										
										
											2020-05-23 10:58:59 +02:00
										 |  |  |                         final isPast = scheduled.compareTo(now) <= 0; | 
					
						
							| 
									
										
										
										
											2020-05-23 10:58:06 +02:00
										 |  |  |                         final dateString = scheduled.dateString(context); | 
					
						
							| 
									
										
										
										
											2020-05-21 20:25:25 +02:00
										 |  |  |                         final timeOfDayString = | 
					
						
							|  |  |  |                             scheduled.timeOfDay.format(context); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                         return Dismissible( | 
					
						
							|  |  |  |                           key: ValueKey(memo.id), | 
					
						
							|  |  |  |                           secondaryBackground: Container( | 
					
						
							|  |  |  |                             padding: const EdgeInsets.all(8.0), | 
					
						
							|  |  |  |                             alignment: Alignment.centerRight, | 
					
						
							|  |  |  |                             color: Colors.amber, | 
					
						
							|  |  |  |                             child: const Icon(Icons.done), | 
					
						
							|  |  |  |                           ), | 
					
						
							|  |  |  |                           background: Container( | 
					
						
							|  |  |  |                             padding: const EdgeInsets.all(8.0), | 
					
						
							|  |  |  |                             alignment: Alignment.centerLeft, | 
					
						
							|  |  |  |                             color: Colors.amber, | 
					
						
							|  |  |  |                             child: const Icon(Icons.done), | 
					
						
							|  |  |  |                           ), | 
					
						
							|  |  |  |                           child: ListTile( | 
					
						
							|  |  |  |                             title: Text(memo.text), | 
					
						
							| 
									
										
										
										
											2020-05-23 10:58:06 +02:00
										 |  |  |                             subtitle: Text( | 
					
						
							| 
									
										
										
										
											2020-05-23 10:58:59 +02:00
										 |  |  |                               l10n.scheduled(dateString, timeOfDayString), | 
					
						
							|  |  |  |                               style: TextStyle( | 
					
						
							|  |  |  |                                 color: isPast ? Colors.red : null, | 
					
						
							|  |  |  |                               ), | 
					
						
							|  |  |  |                             ), | 
					
						
							| 
									
										
										
										
											2020-05-21 20:25:25 +02:00
										 |  |  |                             onTap: () async { | 
					
						
							|  |  |  |                               final result = | 
					
						
							|  |  |  |                                   await _showMemoEditor(context, memo); | 
					
						
							|  |  |  |                               if (result != null) { | 
					
						
							|  |  |  |                                 await backend.updateMemo(index, result); | 
					
						
							|  |  |  |                               } | 
					
						
							|  |  |  |                             }, | 
					
						
							|  |  |  |                           ), | 
					
						
							|  |  |  |                           onDismissed: (_) async { | 
					
						
							|  |  |  |                             await backend.deleteMemo(index); | 
					
						
							| 
									
										
										
										
											2020-05-23 11:42:18 +02:00
										 |  |  |                             scaffold.showSnackBar( | 
					
						
							| 
									
										
										
										
											2020-05-21 20:25:25 +02:00
										 |  |  |                               SnackBar( | 
					
						
							| 
									
										
										
										
											2020-05-23 10:58:06 +02:00
										 |  |  |                                 content: Text(l10n.deleted(memo.text)), | 
					
						
							| 
									
										
										
										
											2020-05-21 20:25:25 +02:00
										 |  |  |                                 action: SnackBarAction( | 
					
						
							| 
									
										
										
										
											2020-05-23 10:58:06 +02:00
										 |  |  |                                   label: l10n.undo, | 
					
						
							| 
									
										
										
										
											2020-05-21 20:25:25 +02:00
										 |  |  |                                   onPressed: () async { | 
					
						
							|  |  |  |                                     await backend.addMemo(memo); | 
					
						
							|  |  |  |                                   }, | 
					
						
							|  |  |  |                                 ), | 
					
						
							|  |  |  |                               ), | 
					
						
							|  |  |  |                             ); | 
					
						
							|  |  |  |                           }, | 
					
						
							|  |  |  |                         ); | 
					
						
							|  |  |  |                       }, | 
					
						
							|  |  |  |                     ); | 
					
						
							|  |  |  |                   } else { | 
					
						
							|  |  |  |                     return Center( | 
					
						
							| 
									
										
										
										
											2020-05-23 13:31:13 +02:00
										 |  |  |                       child: Column( | 
					
						
							|  |  |  |                         mainAxisAlignment: MainAxisAlignment.center, | 
					
						
							|  |  |  |                         children: <Widget>[ | 
					
						
							|  |  |  |                           Icon( | 
					
						
							|  |  |  |                             Icons.notifications_off, | 
					
						
							|  |  |  |                             color: Colors.grey[300], | 
					
						
							|  |  |  |                             size: 128.0, | 
					
						
							|  |  |  |                           ), | 
					
						
							|  |  |  |                           SizedBox( | 
					
						
							|  |  |  |                             height: 8.0, | 
					
						
							|  |  |  |                           ), | 
					
						
							|  |  |  |                           Text( | 
					
						
							|  |  |  |                             l10n.noReminders, | 
					
						
							|  |  |  |                             style: Theme.of(context).textTheme.headline6.copyWith( | 
					
						
							|  |  |  |                                   color: Colors.grey[300], | 
					
						
							|  |  |  |                                 ), | 
					
						
							|  |  |  |                           ), | 
					
						
							|  |  |  |                           SizedBox( | 
					
						
							|  |  |  |                             height: 64.0, | 
					
						
							|  |  |  |                           ), | 
					
						
							|  |  |  |                         ], | 
					
						
							| 
									
										
										
										
											2020-05-21 20:25:25 +02:00
										 |  |  |                       ), | 
					
						
							|  |  |  |                     ); | 
					
						
							|  |  |  |                   } | 
					
						
							|  |  |  |                 } else { | 
					
						
							|  |  |  |                   return Container(); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |               }, | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |       floatingActionButton: FloatingActionButton( | 
					
						
							|  |  |  |         child: const Icon(Icons.add), | 
					
						
							|  |  |  |         onPressed: () async { | 
					
						
							|  |  |  |           final result = await _showMemoEditor(context); | 
					
						
							|  |  |  |           if (result != null) { | 
					
						
							|  |  |  |             await backend.addMemo(result); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |       ), | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |