Convert add instance and account dialogs to pages
This commit is contained in:
parent
33f57b7e54
commit
5b4107aee0
|
@ -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,
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue