memor/lib/home_screen.dart

170 lines
5.9 KiB
Dart
Raw Normal View History

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) {
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);
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);
}
},
),
);
}
}