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 '../hooks/stores.dart';
|
||||||
import '../util/goto.dart';
|
import '../util/goto.dart';
|
||||||
|
import 'add_account.dart';
|
||||||
|
import 'add_instance.dart';
|
||||||
|
|
||||||
class SettingsPage extends StatelessWidget {
|
class SettingsPage extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
|
@ -102,11 +104,8 @@ class AccountsConfigPage extends HookWidget {
|
||||||
),
|
),
|
||||||
floatingActionButton: FloatingActionButton(
|
floatingActionButton: FloatingActionButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
showDialog(
|
showCupertinoModalPopup(
|
||||||
context: context,
|
context: context, builder: (_) => AddInstancePage());
|
||||||
builder: (_) =>
|
|
||||||
_AccountsConfigAddInstanceDialog(scaffoldKey: _scaffoldKey),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
child: Icon(Icons.add),
|
child: Icon(Icons.add),
|
||||||
),
|
),
|
||||||
|
@ -139,13 +138,9 @@ class AccountsConfigPage extends HookWidget {
|
||||||
leading: Icon(Icons.add),
|
leading: Icon(Icons.add),
|
||||||
title: Text('Add account'),
|
title: Text('Add account'),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
showDialog(
|
showCupertinoModalPopup(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (_) => _AccountsConfigAddAccountDialog(
|
builder: (_) => AddAccountPage(instanceUrl: entry.key));
|
||||||
scaffoldKey: _scaffoldKey,
|
|
||||||
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 {
|
class _SectionHeading extends StatelessWidget {
|
||||||
final String text;
|
final String text;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue