Skip to content

Commit 0b574bc

Browse files
authored
Improvements to log out flow (#980)
* Fix a couple logout issues * Show modal when logging out of account * Rename flag
1 parent 29a43cd commit 0b574bc

3 files changed

Lines changed: 72 additions & 27 deletions

File tree

lib/account/utils/profiles.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import 'package:thunder/core/auth/bloc/auth_bloc.dart';
66
import 'package:thunder/thunder/bloc/thunder_bloc.dart';
77
import 'package:thunder/account/widgets/profile_modal_body.dart';
88

9-
void showProfileModalSheet(BuildContext context) {
9+
void showProfileModalSheet(BuildContext context, {bool showLogoutDialog = false}) {
1010
AuthBloc authBloc = context.read<AuthBloc>();
1111
ThunderBloc thunderBloc = context.read<ThunderBloc>();
1212

@@ -20,9 +20,9 @@ void showProfileModalSheet(BuildContext context) {
2020
BlocProvider.value(value: authBloc),
2121
BlocProvider.value(value: thunderBloc),
2222
],
23-
child: const FractionallySizedBox(
23+
child: FractionallySizedBox(
2424
heightFactor: 0.9,
25-
child: ProfileModalBody(),
25+
child: ProfileModalBody(showLogoutDialog: showLogoutDialog),
2626
),
2727
);
2828
},

lib/account/widgets/profile_modal_body.dart

Lines changed: 66 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
1717

1818
class ProfileModalBody extends StatefulWidget {
1919
final bool anonymous;
20+
final bool showLogoutDialog;
2021

21-
const ProfileModalBody({super.key, this.anonymous = false});
22+
const ProfileModalBody({super.key, this.anonymous = false, this.showLogoutDialog = false});
2223

2324
static final GlobalKey<NavigatorState> shellNavigatorKey = GlobalKey<NavigatorState>();
2425

@@ -40,7 +41,14 @@ class _ProfileModalBodyState extends State<ProfileModalBody> {
4041
return Navigator(
4142
key: ProfileModalBody.shellNavigatorKey,
4243
onPopPage: (route, result) => false,
43-
pages: [MaterialPage(child: ProfileSelect(pushRegister: pushRegister))],
44+
pages: [
45+
MaterialPage(
46+
child: ProfileSelect(
47+
pushRegister: pushRegister,
48+
showLogoutDialog: widget.showLogoutDialog,
49+
),
50+
)
51+
],
4452
onGenerateRoute: _onGenerateRoute,
4553
);
4654
}
@@ -49,7 +57,10 @@ class _ProfileModalBodyState extends State<ProfileModalBody> {
4957
late Widget page;
5058
switch (settings.name) {
5159
case '/':
52-
page = ProfileSelect(pushRegister: pushRegister);
60+
page = ProfileSelect(
61+
pushRegister: pushRegister,
62+
showLogoutDialog: widget.showLogoutDialog,
63+
);
5364
break;
5465

5566
case '/login':
@@ -68,7 +79,13 @@ class _ProfileModalBodyState extends State<ProfileModalBody> {
6879

6980
class ProfileSelect extends StatefulWidget {
7081
final void Function({bool anonymous}) pushRegister;
71-
ProfileSelect({Key? key, required this.pushRegister}) : super(key: key);
82+
final bool showLogoutDialog;
83+
84+
const ProfileSelect({
85+
super.key,
86+
required this.pushRegister,
87+
this.showLogoutDialog = false,
88+
});
7289

7390
@override
7491
State<ProfileSelect> createState() => _ProfileSelectState();
@@ -82,6 +99,18 @@ class _ProfileSelectState extends State<ProfileSelect> {
8299
// Represents the ID of the account/instance we're currently logging out of / removing
83100
String? loggingOutId;
84101

102+
@override
103+
void initState() {
104+
super.initState();
105+
106+
if (widget.showLogoutDialog) {
107+
WidgetsBinding.instance.addPostFrameCallback((_) async {
108+
await Future.delayed(const Duration(milliseconds: 250));
109+
_logOutOfActiveAccount();
110+
});
111+
}
112+
}
113+
85114
@override
86115
Widget build(BuildContext context) {
87116
final theme = Theme.of(context);
@@ -295,25 +324,7 @@ class _ProfileSelectState extends State<ProfileSelect> {
295324
child: CircularProgressIndicator(),
296325
)
297326
: Icon(Icons.logout, semanticLabel: AppLocalizations.of(context)!.logOut),
298-
onPressed: () async {
299-
if (await showLogOutDialog(context)) {
300-
setState(() => loggingOutId = accounts![index].account.id);
301-
302-
await Future.delayed(const Duration(milliseconds: 1000), () {
303-
if ((anonymousInstances?.length ?? 0) > 0) {
304-
context.read<ThunderBloc>().add(OnSetCurrentAnonymousInstance(anonymousInstances!.last.instance));
305-
context.read<AuthBloc>().add(InstanceChanged(instance: anonymousInstances!.last.instance));
306-
} else {
307-
context.read<AuthBloc>().add(SwitchAccount(accountId: accounts!.lastWhere((account) => account.account.id != currentAccountId).account.id));
308-
}
309-
310-
setState(() {
311-
accounts = null;
312-
loggingOutId = null;
313-
});
314-
});
315-
}
316-
},
327+
onPressed: () => _logOutOfActiveAccount(activeAccountId: accounts![index].account.id),
317328
)
318329
: IconButton(
319330
icon: loggingOutId == accounts![index].account.id
@@ -527,6 +538,38 @@ class _ProfileSelectState extends State<ProfileSelect> {
527538
);
528539
}
529540

541+
Future<void> _logOutOfActiveAccount({String? activeAccountId}) async {
542+
activeAccountId ??= context.read<AuthBloc>().state.account?.id;
543+
544+
final AuthBloc authBloc = context.read<AuthBloc>();
545+
final ThunderBloc thunderBloc = context.read<ThunderBloc>();
546+
547+
final List<Account> accountsNotCurrent = (await Account.accounts()).where((a) => a.id != activeAccountId).toList();
548+
549+
if (context.mounted && activeAccountId != null && await showLogOutDialog(context)) {
550+
setState(() => loggingOutId = activeAccountId);
551+
552+
await Future.delayed(const Duration(milliseconds: 1000), () {
553+
if ((anonymousInstances?.length ?? 0) > 0) {
554+
thunderBloc.add(OnSetCurrentAnonymousInstance(anonymousInstances!.last.instance));
555+
authBloc.add(InstanceChanged(instance: anonymousInstances!.last.instance));
556+
} else if (accountsNotCurrent.isNotEmpty) {
557+
authBloc.add(SwitchAccount(accountId: accountsNotCurrent.last.id));
558+
} else {
559+
// No accounts and no anonymous instances left. Create a new one.
560+
authBloc.add(const LogOutOfAllAccounts());
561+
thunderBloc.add(const OnAddAnonymousInstance('lemmy.ml'));
562+
thunderBloc.add(const OnSetCurrentAnonymousInstance('lemmy.ml'));
563+
}
564+
565+
setState(() {
566+
accounts = null;
567+
loggingOutId = null;
568+
});
569+
});
570+
}
571+
}
572+
530573
Future<void> fetchAccounts() async {
531574
List<Account> accounts = await Account.accounts();
532575

lib/user/pages/user_page.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
44
import 'package:swipeable_page_route/swipeable_page_route.dart';
55

66
import 'package:thunder/account/bloc/account_bloc.dart';
7+
import 'package:thunder/account/models/account.dart';
78
import 'package:thunder/account/utils/profiles.dart';
9+
import 'package:thunder/core/auth/bloc/auth_bloc.dart';
810
import 'package:thunder/shared/primitive_wrapper.dart';
911
import 'package:thunder/shared/snackbar.dart';
1012
import 'package:thunder/thunder/bloc/thunder_bloc.dart';
@@ -47,7 +49,7 @@ class _UserPageState extends State<UserPage> {
4749
scrolledUnderElevation: 0,
4850
leading: widget.isAccountUser
4951
? IconButton(
50-
onPressed: () => showLogOutDialog(context),
52+
onPressed: () => showProfileModalSheet(context, showLogoutDialog: true),
5153
icon: Icon(
5254
Icons.logout,
5355
semanticLabel: AppLocalizations.of(context)!.logOut,

0 commit comments

Comments
 (0)