Boostrap managing account page

This commit is contained in:
shilangyu 2021-01-05 23:51:19 +00:00
parent 2536e3cbf8
commit 50bd46cf88
2 changed files with 179 additions and 14 deletions

View File

@ -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'),
),
],
);
},
),
);
}
}

View File

@ -10,6 +10,7 @@ import '../util/goto.dart';
import '../widgets/about_tile.dart'; import '../widgets/about_tile.dart';
import 'add_account.dart'; import 'add_account.dart';
import 'add_instance.dart'; import 'add_instance.dart';
import 'manage_account.dart';
/// Page with a list of different settings sections /// Page with a list of different settings sections
class SettingsPage extends StatelessWidget { 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), const SizedBox(height: 40),
Slidable( Slidable(
actionPane: const SlidableBehindActionPane(), actionPane: const SlidableBehindActionPane(),
secondaryActions: [ secondaryActions: [
IconSlideAction( IconSlideAction(
onTap: () => removeInstanceDialog(entry.key), onTap: () => removeInstanceDialog(instance),
icon: Icons.delete_sweep, icon: Icons.delete_sweep,
color: Colors.red, color: Colors.red,
), ),
], ],
key: Key(entry.key), key: Key(instance),
// TODO: missing ripple effect
child: Container( child: Container(
color: theme.canvasColor, color: theme.scaffoldBackgroundColor,
child: ListTile( child: ListTile(
dense: true, dense: true,
contentPadding: EdgeInsets.zero, 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( Slidable(
actionPane: const SlidableBehindActionPane(), actionPane: const SlidableBehindActionPane(),
key: Key('$username@${entry.key}'), key: Key('$username@$instance'),
secondaryActions: [ secondaryActions: [
IconSlideAction( IconSlideAction(
onTap: () => removeUserDialog(entry.key, username), onTap: () => removeUserDialog(instance, username),
icon: Icons.delete_sweep, icon: Icons.delete_sweep,
color: Colors.red, color: Colors.red,
), ),
], ],
// TODO: missing ripple effect
child: Container( child: Container(
decoration: BoxDecoration(color: theme.canvasColor), color: theme.scaffoldBackgroundColor,
child: ListTile( child: ListTile(
trailing: trailing:
username == accountsStore.defaultUsernameFor(entry.key) username == accountsStore.defaultUsernameFor(instance)
? Icon( ? Icon(
Icons.check_circle_outline, Icons.check_circle_outline,
color: theme.accentColor, color: theme.accentColor,
@ -249,21 +252,28 @@ class AccountsConfigPage extends HookWidget {
: null, : null,
title: Text(username), title: Text(username),
onLongPress: () { 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( ListTile(
leading: const Icon(Icons.add), leading: const Icon(Icons.add),
title: const Text('Add account'), title: const Text('Add account'),
onTap: () { onTap: () {
showCupertinoModalPopup( showCupertinoModalPopup(
context: context, context: context,
builder: (_) => AddAccountPage(instanceHost: entry.key)); builder: (_) => AddAccountPage(instanceHost: instance));
}, },
), ),
] ]