lemmur-app-android/lib/pages/settings.dart

297 lines
9.8 KiB
Dart
Raw Normal View History

import 'package:flutter/cupertino.dart';
2020-08-31 16:17:39 +02:00
import 'package:flutter/material.dart';
2020-09-08 00:34:09 +02:00
import 'package:flutter_hooks/flutter_hooks.dart';
2020-08-31 16:17:39 +02:00
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
2020-08-31 16:17:39 +02:00
2020-09-16 23:22:04 +02:00
import '../hooks/stores.dart';
import '../util/goto.dart';
import 'add_account.dart';
import 'add_instance.dart';
2020-08-31 16:17:39 +02:00
2020-09-03 14:33:17 +02:00
class SettingsPage extends StatelessWidget {
2020-08-31 16:17:39 +02:00
@override
Widget build(BuildContext context) {
2020-09-16 23:22:04 +02:00
final theme = Theme.of(context);
2020-08-31 16:17:39 +02:00
return Scaffold(
appBar: AppBar(
brightness: theme.brightness,
2020-08-31 16:17:39 +02:00
backgroundColor: theme.scaffoldBackgroundColor,
shadowColor: Colors.transparent,
iconTheme: theme.iconTheme,
title: Text('Settings', style: theme.textTheme.headline6),
centerTitle: true,
),
body: Container(
child: ListView(
children: [
ListTile(
leading: Icon(Icons.person),
title: Text('Accounts'),
onTap: () {
goTo(context, (_) => AccountsConfigPage());
},
2020-08-31 16:17:39 +02:00
),
ListTile(
leading: Icon(Icons.color_lens),
title: Text('Appearance'),
onTap: () {
goTo(context, (_) => AppearanceConfigPage());
2020-08-31 16:17:39 +02:00
},
)
],
),
),
);
}
}
2020-09-17 00:24:49 +02:00
class AppearanceConfigPage extends HookWidget {
2020-08-31 16:17:39 +02:00
@override
Widget build(BuildContext context) {
2020-09-16 23:22:04 +02:00
final theme = Theme.of(context);
2020-09-16 23:15:42 +02:00
final configStore = useConfigStore();
2020-08-31 16:17:39 +02:00
return Scaffold(
appBar: AppBar(
brightness: theme.brightness,
2020-08-31 16:17:39 +02:00
backgroundColor: theme.scaffoldBackgroundColor,
shadowColor: Colors.transparent,
iconTheme: theme.iconTheme,
title: Text('Appearance', style: theme.textTheme.headline6),
centerTitle: true,
),
body: Observer(
builder: (ctx) => ListView(
2020-08-31 16:17:39 +02:00
children: [
2020-09-03 23:14:26 +02:00
_SectionHeading('Theme'),
2020-08-31 16:17:39 +02:00
for (final theme in ThemeMode.values)
RadioListTile<ThemeMode>(
value: theme,
title: Text(theme.toString().split('.')[1]),
2020-09-16 23:15:42 +02:00
groupValue: configStore.theme,
2020-08-31 16:17:39 +02:00
onChanged: (selected) {
2020-09-16 23:15:42 +02:00
configStore.theme = selected;
2020-08-31 16:17:39 +02:00
},
),
2020-09-08 10:23:08 +02:00
SwitchListTile(
2020-09-08 10:24:47 +02:00
title: Text('AMOLED dark mode'),
2020-09-16 23:15:42 +02:00
value: configStore.amoledDarkMode,
2020-09-08 10:23:08 +02:00
onChanged: (checked) {
2020-09-16 23:15:42 +02:00
configStore.amoledDarkMode = checked;
2020-09-08 10:23:08 +02:00
})
2020-08-31 16:17:39 +02:00
],
),
),
);
}
}
class AccountsConfigPage extends HookWidget {
2020-09-08 00:34:09 +02:00
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey();
@override
Widget build(BuildContext context) {
2020-09-16 23:22:04 +02:00
final theme = Theme.of(context);
2020-09-16 23:15:42 +02:00
final accountsStore = useAccountsStore();
2020-09-22 01:05:20 +02:00
removeInstanceDialog(String instanceUrl) async {
if (await showDialog<bool>(
context: context,
builder: (context) => AlertDialog(
2020-09-22 01:05:20 +02:00
title: Text('Remove instance?'),
content: Text('Are you sure you want to remove $instanceUrl?'),
actions: [
2020-09-23 23:37:26 +02:00
FlatButton(
child: Text('no'),
onPressed: () => Navigator.of(context).pop(false),
),
FlatButton(
child: Text('yes'),
onPressed: () => Navigator.of(context).pop(true),
),
],
),
) ??
false) {
accountsStore.removeInstance(instanceUrl);
}
}
2020-09-23 23:39:41 +02:00
Future<void> removeUserDialog(String instanceUrl, String username) async {
if (await showDialog<bool>(
context: context,
builder: (context) => AlertDialog(
title: Text('Remove user?'),
content: Text(
'Are you sure you want to remove $username@$instanceUrl?'),
actions: [
2020-09-23 23:37:26 +02:00
FlatButton(
child: Text('no'),
onPressed: () => Navigator.of(context).pop(false),
),
FlatButton(
child: Text('yes'),
onPressed: () => Navigator.of(context).pop(true),
),
],
),
) ??
false) {
accountsStore.removeAccount(instanceUrl, username);
}
}
return Scaffold(
2020-09-08 00:34:09 +02:00
key: _scaffoldKey,
appBar: AppBar(
backgroundColor: theme.scaffoldBackgroundColor,
brightness: theme.brightness,
shadowColor: Colors.transparent,
iconTheme: theme.iconTheme,
title: Text('Accounts', style: theme.textTheme.headline6),
centerTitle: true,
),
floatingActionButton: SpeedDial(
animatedIcon: AnimatedIcons.menu_close, // TODO: change to + => x
closeManually: false,
curve: Curves.bounceIn,
tooltip: 'Add account or instance',
2020-09-08 00:34:09 +02:00
child: Icon(Icons.add),
2020-09-24 15:48:05 +02:00
overlayColor: theme.canvasColor,
children: [
SpeedDialChild(
child: Icon(Icons.person_add),
label: 'Add account',
2020-09-24 15:48:05 +02:00
labelBackgroundColor: theme.canvasColor,
onTap: () => showCupertinoModalPopup(
context: context,
builder: (_) =>
AddAccountPage(instanceUrl: accountsStore.instances.last)),
),
SpeedDialChild(
child: Icon(Icons.dns),
2020-09-24 15:48:05 +02:00
labelBackgroundColor: theme.canvasColor,
label: 'Add instance',
onTap: () => showCupertinoModalPopup(
context: context, builder: (_) => AddInstancePage()),
),
],
2020-09-08 00:34:09 +02:00
),
body: Observer(
builder: (ctx) {
2020-09-16 23:22:04 +02:00
final theme = Theme.of(context);
return ListView(
children: [
if (accountsStore.tokens.isEmpty)
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(top: 100),
child: FlatButton.icon(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
onPressed: () => showCupertinoModalPopup(
context: context,
builder: (_) => AddInstancePage(),
),
icon: Icon(Icons.add),
label: Text('Add instance')),
),
],
),
for (final entry in accountsStore.tokens.entries) ...[
SizedBox(height: 40),
Slidable(
actionPane: SlidableBehindActionPane(),
secondaryActions: [
IconSlideAction(
closeOnTap: true,
2020-09-22 01:05:20 +02:00
onTap: () => removeInstanceDialog(entry.key),
icon: Icons.delete_sweep,
color: Colors.red,
),
],
key: Key(entry.key),
child: Container(
color: theme.canvasColor,
child: ListTile(
dense: true,
contentPadding: EdgeInsets.only(left: 0, top: 0),
title: _SectionHeading(entry.key),
),
),
),
2020-09-16 23:22:04 +02:00
for (final username in entry.value.keys) ...[
Slidable(
actionPane: SlidableBehindActionPane(),
key: Key('$username@${entry.key}'),
secondaryActions: [
IconSlideAction(
closeOnTap: true,
onTap: () => removeUserDialog(entry.key, username),
icon: Icons.delete_sweep,
color: Colors.red,
),
],
child: Container(
decoration: BoxDecoration(color: theme.canvasColor),
child: ListTile(
trailing: username ==
accountsStore.defaultUsernameFor(entry.key)
2020-09-03 23:14:26 +02:00
? Icon(
Icons.check_circle_outline,
color: theme.accentColor,
)
: null,
title: Text(username),
onLongPress: () {
accountsStore.setDefaultAccountFor(
entry.key, username);
},
onTap: () {}, // TODO: go to managing account
),
),
),
],
if (entry.value.keys.isEmpty)
ListTile(
leading: Icon(Icons.add),
title: Text('Add account'),
onTap: () {
showCupertinoModalPopup(
context: context,
builder: (_) =>
AddAccountPage(instanceUrl: entry.key));
},
),
]
2020-09-08 16:37:58 +02:00
],
);
},
),
);
}
}
2020-09-03 23:14:26 +02:00
class _SectionHeading extends StatelessWidget {
final String text;
const _SectionHeading(this.text);
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Padding(
child: Text(text.toUpperCase(),
style: theme.textTheme.subtitle2.copyWith(color: theme.accentColor)),
padding: EdgeInsets.only(left: 20, top: 0),
2020-09-03 23:14:26 +02:00
);
}
}