Boostrap managing account page
This commit is contained in:
parent
2536e3cbf8
commit
50bd46cf88
|
@ -0,0 +1,155 @@
|
|||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:lemmy_api_client/lemmy_api_client.dart';
|
||||
|
||||
import '../hooks/stores.dart';
|
||||
|
||||
class ManageAccount extends HookWidget {
|
||||
final String instanceHost;
|
||||
final String username;
|
||||
|
||||
const ManageAccount({@required this.instanceHost, @required this.username})
|
||||
: assert(instanceHost != null),
|
||||
assert(username != null);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final accountStore = useAccountsStore();
|
||||
final theme = Theme.of(context);
|
||||
|
||||
final displayNameController = useTextEditingController();
|
||||
final bioController = useTextEditingController();
|
||||
final emailController = useTextEditingController();
|
||||
|
||||
final userViewFuture = useMemoized(() async {
|
||||
final userDetails = await LemmyApi(instanceHost).v1.getUserDetails(
|
||||
sort: SortType.active,
|
||||
savedOnly: false,
|
||||
auth: accountStore.tokens[instanceHost][username].raw,
|
||||
username: username);
|
||||
|
||||
return userDetails.user;
|
||||
});
|
||||
|
||||
final uploadButton = ElevatedButton(
|
||||
onPressed: () {},
|
||||
style: ElevatedButton.styleFrom(
|
||||
visualDensity: VisualDensity.comfortable,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
children: const [Text('upload'), Icon(Icons.publish)],
|
||||
));
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: theme.scaffoldBackgroundColor,
|
||||
brightness: theme.brightness,
|
||||
shadowColor: Colors.transparent,
|
||||
iconTheme: theme.iconTheme,
|
||||
title:
|
||||
Text('$instanceHost@$username', style: theme.textTheme.headline6),
|
||||
centerTitle: true,
|
||||
),
|
||||
body: FutureBuilder<UserView>(
|
||||
future: userViewFuture,
|
||||
builder: (_, userViewSnap) {
|
||||
if (userViewSnap.hasError) {
|
||||
return Center(
|
||||
child: Text('Error: ${userViewSnap.error?.toString()}'));
|
||||
}
|
||||
if (!userViewSnap.hasData) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
|
||||
final userView = userViewSnap.data;
|
||||
|
||||
bioController.text = userView.bio;
|
||||
displayNameController.text = userView.preferredUsername;
|
||||
emailController.text = userView.email;
|
||||
|
||||
return ListView(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('Avatar', style: theme.textTheme.headline6),
|
||||
uploadButton
|
||||
],
|
||||
),
|
||||
if (userView.avatar != null)
|
||||
CachedNetworkImage(
|
||||
imageUrl: userView.avatar,
|
||||
errorWidget: (_, __, ___) => const Icon(Icons.error),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text('Banner', style: theme.textTheme.headline6),
|
||||
uploadButton
|
||||
],
|
||||
),
|
||||
if (userView.banner != null)
|
||||
CachedNetworkImage(
|
||||
imageUrl: userView.banner,
|
||||
errorWidget: (_, __, ___) => const Icon(Icons.error),
|
||||
),
|
||||
Text('Display Name', style: theme.textTheme.headline6),
|
||||
TextField(
|
||||
controller: displayNameController,
|
||||
decoration: InputDecoration(
|
||||
isDense: true,
|
||||
contentPadding:
|
||||
const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
),
|
||||
),
|
||||
Text('Bio', style: theme.textTheme.headline6),
|
||||
TextField(
|
||||
controller: bioController,
|
||||
minLines: 4,
|
||||
maxLines: 10,
|
||||
decoration: InputDecoration(
|
||||
contentPadding:
|
||||
const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
),
|
||||
),
|
||||
Text('Email', style: theme.textTheme.headline6),
|
||||
TextField(
|
||||
controller: emailController,
|
||||
decoration: InputDecoration(
|
||||
isDense: true,
|
||||
contentPadding:
|
||||
const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
),
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () {},
|
||||
style: ElevatedButton.styleFrom(
|
||||
primary: Colors.red,
|
||||
visualDensity: VisualDensity.comfortable,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
),
|
||||
child: const Text('DELETE ACCOUNT'),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ import '../util/goto.dart';
|
|||
import '../widgets/about_tile.dart';
|
||||
import 'add_account.dart';
|
||||
import 'add_instance.dart';
|
||||
import 'manage_account.dart';
|
||||
|
||||
/// Page with a list of different settings sections
|
||||
class SettingsPage extends StatelessWidget {
|
||||
|
@ -205,43 +206,45 @@ class AccountsConfigPage extends HookWidget {
|
|||
),
|
||||
],
|
||||
),
|
||||
for (final entry in accountsStore.tokens.entries) ...[
|
||||
for (final instance in accountsStore.instances) ...[
|
||||
const SizedBox(height: 40),
|
||||
Slidable(
|
||||
actionPane: const SlidableBehindActionPane(),
|
||||
secondaryActions: [
|
||||
IconSlideAction(
|
||||
onTap: () => removeInstanceDialog(entry.key),
|
||||
onTap: () => removeInstanceDialog(instance),
|
||||
icon: Icons.delete_sweep,
|
||||
color: Colors.red,
|
||||
),
|
||||
],
|
||||
key: Key(entry.key),
|
||||
key: Key(instance),
|
||||
// TODO: missing ripple effect
|
||||
child: Container(
|
||||
color: theme.canvasColor,
|
||||
color: theme.scaffoldBackgroundColor,
|
||||
child: ListTile(
|
||||
dense: true,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
title: _SectionHeading(entry.key),
|
||||
title: _SectionHeading(instance),
|
||||
),
|
||||
),
|
||||
),
|
||||
for (final username in entry.value.keys) ...[
|
||||
for (final username in accountsStore.tokens[instance].keys) ...[
|
||||
Slidable(
|
||||
actionPane: const SlidableBehindActionPane(),
|
||||
key: Key('$username@${entry.key}'),
|
||||
key: Key('$username@$instance'),
|
||||
secondaryActions: [
|
||||
IconSlideAction(
|
||||
onTap: () => removeUserDialog(entry.key, username),
|
||||
onTap: () => removeUserDialog(instance, username),
|
||||
icon: Icons.delete_sweep,
|
||||
color: Colors.red,
|
||||
),
|
||||
],
|
||||
// TODO: missing ripple effect
|
||||
child: Container(
|
||||
decoration: BoxDecoration(color: theme.canvasColor),
|
||||
color: theme.scaffoldBackgroundColor,
|
||||
child: ListTile(
|
||||
trailing:
|
||||
username == accountsStore.defaultUsernameFor(entry.key)
|
||||
username == accountsStore.defaultUsernameFor(instance)
|
||||
? Icon(
|
||||
Icons.check_circle_outline,
|
||||
color: theme.accentColor,
|
||||
|
@ -249,21 +252,28 @@ class AccountsConfigPage extends HookWidget {
|
|||
: null,
|
||||
title: Text(username),
|
||||
onLongPress: () {
|
||||
accountsStore.setDefaultAccountFor(entry.key, username);
|
||||
accountsStore.setDefaultAccountFor(instance, username);
|
||||
},
|
||||
onTap: () {
|
||||
goTo(
|
||||
context,
|
||||
(_) => ManageAccount(
|
||||
instanceHost: instance,
|
||||
username: username,
|
||||
));
|
||||
},
|
||||
onTap: () {}, // TODO: go to managing account
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
if (entry.value.keys.isEmpty)
|
||||
if (accountsStore.tokens[instance].keys.isEmpty)
|
||||
ListTile(
|
||||
leading: const Icon(Icons.add),
|
||||
title: const Text('Add account'),
|
||||
onTap: () {
|
||||
showCupertinoModalPopup(
|
||||
context: context,
|
||||
builder: (_) => AddAccountPage(instanceHost: entry.key));
|
||||
builder: (_) => AddAccountPage(instanceHost: instance));
|
||||
},
|
||||
),
|
||||
]
|
||||
|
|
Loading…
Reference in New Issue