Convert add instance and account dialogs to pages

This commit is contained in:
krawieck 2020-09-19 01:34:04 +02:00
parent 33f57b7e54
commit 5b4107aee0
3 changed files with 252 additions and 141 deletions

167
lib/pages/add_account.dart Normal file
View File

@ -0,0 +1,167 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:lemmur/hooks/stores.dart';
import 'package:lemmur/pages/add_instance.dart';
import '../widgets/bottom_modal.dart';
class AddAccountPage extends HookWidget {
final String instanceUrl;
const AddAccountPage({@required this.instanceUrl})
: assert(instanceUrl != null);
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final usernameController = useTextEditingController();
final passwordController = useTextEditingController();
useValueListenable(usernameController);
useValueListenable(passwordController);
final accountsStore = useAccountsStore();
final loading = useState(false);
final selectedInstance = useState(instanceUrl);
selectInstance() async {
final val = await showModalBottomSheet<String>(
backgroundColor: Colors.transparent,
isScrollControlled: true,
context: context,
builder: (context) => BottomModal(
title: 'select instance',
child: Column(children: [
for (final i in accountsStore.users.keys)
RadioListTile<String>(
value: i,
groupValue: selectedInstance.value,
onChanged: (val) {
Navigator.of(context).pop(val);
},
title: Text(i),
),
ListTile(
leading: Padding(
padding: const EdgeInsets.all(8),
child: Icon(Icons.add),
),
title: Text('Add instance'),
onTap: () async {
final val = await showCupertinoModalPopup<String>(
context: context,
builder: (context) => AddInstancePage(),
);
Navigator.of(context).pop(val);
},
),
]),
),
);
if (val != null) {
selectedInstance.value = val;
}
}
handleOnAdd() async {
try {
loading.value = true;
await accountsStore.addAccount(
instanceUrl,
usernameController.text,
passwordController.text,
);
} on Exception catch (err) {
Scaffold.of(context).showSnackBar(SnackBar(
content: Text(err.toString()),
));
}
loading.value = false;
Navigator.of(context).pop();
}
return Scaffold(
appBar: AppBar(
leading: CloseButton(),
actionsIconTheme: theme.iconTheme,
iconTheme: theme.iconTheme,
textTheme: theme.textTheme,
title: Text('Add account'),
backgroundColor: theme.canvasColor,
shadowColor: Colors.transparent,
),
body: Padding(
padding: const EdgeInsets.all(15),
child: ListView(
children: [
SizedBox(height: 150),
FlatButton(
onPressed: selectInstance,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(selectedInstance.value),
Icon(Icons.arrow_drop_down),
],
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
TextField(
autofocus: true,
controller: usernameController,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(13),
),
labelText: 'Username or email',
),
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(10),
// ),
),
const SizedBox(height: 5),
TextField(
controller: passwordController,
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(13),
),
labelText: 'Password',
),
),
Row(
// mainAxisAlignment: MainAxisAlignment.end,
children: [
FlatButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
child: Text('Cancel'),
onPressed: () => Navigator.of(context).pop(),
),
Spacer(),
RaisedButton(
color: theme.accentColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
child: !loading.value
? Text('Add')
: CircularProgressIndicator(),
onPressed: usernameController.text.isEmpty ||
passwordController.text.isEmpty
? null
: handleOnAdd,
),
],
)
],
),
),
);
}
}

View File

@ -0,0 +1,78 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import '../hooks/stores.dart';
class AddInstancePage extends HookWidget {
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final instanceController = useTextEditingController();
useValueListenable(instanceController);
final accountsStore = useAccountsStore();
final loading = useState(false);
handleOnAdd() async {
try {
loading.value = true;
await accountsStore.addInstance(instanceController.text);
Navigator.of(context).pop(instanceController.text);
} on Exception catch (err) {
Scaffold.of(context).showSnackBar(SnackBar(
content: Text(err.toString()),
));
}
loading.value = false;
Navigator.of(context).pop();
}
return Scaffold(
appBar: AppBar(
backgroundColor: theme.scaffoldBackgroundColor,
shadowColor: Colors.transparent,
iconTheme: theme.iconTheme,
leading: CloseButton(),
actionsIconTheme: theme.iconTheme,
textTheme: theme.textTheme,
title: Text('Add instance'),
),
body: Padding(
padding: const EdgeInsets.all(15),
child: ListView(
children: [
if (false)
CachedNetworkImage(height: 150, width: 150)
else
SizedBox(height: 150),
TextField(
autofocus: true,
controller: instanceController,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'instance url',
),
),
Row(
children: <Widget>[
FlatButton(
child: Text('Cancel'),
onPressed: () => Navigator.of(context).pop(),
),
Spacer(),
RaisedButton(
child: !loading.value
? Text('Add')
: CircularProgressIndicator(),
onPressed:
instanceController.text.isEmpty ? null : handleOnAdd,
),
],
)
],
),
),
);
}
}

View File

@ -5,6 +5,8 @@ import 'package:flutter_mobx/flutter_mobx.dart';
import '../hooks/stores.dart';
import '../util/goto.dart';
import 'add_account.dart';
import 'add_instance.dart';
class SettingsPage extends StatelessWidget {
@override
@ -102,11 +104,8 @@ class AccountsConfigPage extends HookWidget {
),
floatingActionButton: FloatingActionButton(
onPressed: () {
showDialog(
context: context,
builder: (_) =>
_AccountsConfigAddInstanceDialog(scaffoldKey: _scaffoldKey),
);
showCupertinoModalPopup(
context: context, builder: (_) => AddInstancePage());
},
child: Icon(Icons.add),
),
@ -139,13 +138,9 @@ class AccountsConfigPage extends HookWidget {
leading: Icon(Icons.add),
title: Text('Add account'),
onTap: () {
showDialog(
context: context,
builder: (_) => _AccountsConfigAddAccountDialog(
scaffoldKey: _scaffoldKey,
instanceUrl: entry.key,
),
);
showCupertinoModalPopup(
context: context,
builder: (_) => AddAccountPage(instanceUrl: entry.key));
},
),
]
@ -157,135 +152,6 @@ class AccountsConfigPage extends HookWidget {
}
}
class _AccountsConfigAddInstanceDialog extends HookWidget {
final GlobalKey<ScaffoldState> scaffoldKey;
const _AccountsConfigAddInstanceDialog({@required this.scaffoldKey})
: assert(scaffoldKey != null);
@override
Widget build(BuildContext context) {
final instanceController = useTextEditingController();
useValueListenable(instanceController);
final accountsStore = useAccountsStore();
final loading = useState(false);
handleOnAdd() async {
try {
loading.value = true;
await accountsStore.addInstance(instanceController.text);
scaffoldKey.currentState.hideCurrentSnackBar();
} on Exception catch (err) {
scaffoldKey.currentState.showSnackBar(SnackBar(
content: Text(err.toString()),
));
}
loading.value = false;
Navigator.of(context).pop();
}
return AlertDialog(
title: Text('Add instance'),
content: TextField(
autofocus: true,
controller: instanceController,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Instance url',
),
),
actions: <Widget>[
FlatButton(
child: Text('Cancel'),
onPressed: () => Navigator.of(context).pop(),
),
FlatButton(
child: !loading.value ? Text('Add') : CircularProgressIndicator(),
onPressed: instanceController.text.isEmpty ? null : handleOnAdd,
),
],
);
}
}
class _AccountsConfigAddAccountDialog extends HookWidget {
final GlobalKey<ScaffoldState> scaffoldKey;
final String instanceUrl;
const _AccountsConfigAddAccountDialog(
{@required this.scaffoldKey, @required this.instanceUrl})
: assert(scaffoldKey != null),
assert(instanceUrl != null);
@override
Widget build(BuildContext context) {
final usernameController = useTextEditingController();
final passwordController = useTextEditingController();
useValueListenable(usernameController);
useValueListenable(passwordController);
final accountsStore = useAccountsStore();
final loading = useState(false);
handleOnAdd() async {
try {
loading.value = true;
await accountsStore.addAccount(
instanceUrl,
usernameController.text,
passwordController.text,
);
} on Exception catch (err) {
scaffoldKey.currentState.showSnackBar(SnackBar(
content: Text(err.toString()),
));
}
loading.value = false;
Navigator.of(context).pop();
}
return AlertDialog(
title: Text('Add account'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextField(
autofocus: true,
controller: usernameController,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Username or email',
),
),
const SizedBox(height: 5),
TextField(
controller: passwordController,
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Password',
),
),
],
),
actions: <Widget>[
FlatButton(
child: Text('Cancel'),
onPressed: () => Navigator.of(context).pop(),
),
FlatButton(
child: !loading.value ? Text('Add') : CircularProgressIndicator(),
onPressed:
usernameController.text.isEmpty || passwordController.text.isEmpty
? null
: handleOnAdd,
),
],
);
}
}
class _SectionHeading extends StatelessWidget {
final String text;