deadlock cleanup

This commit is contained in:
Christien Rioux 2025-03-21 11:33:58 -04:00
parent 23867a1784
commit 2141dbff21
40 changed files with 254 additions and 253 deletions

View file

@ -23,7 +23,6 @@ class AccountInfoCubit extends Cubit<AccountInfo> {
if (acctInfo != null) {
emit(acctInfo);
}
break;
}
});
}

View file

@ -20,7 +20,6 @@ class LocalAccountsCubit extends Cubit<LocalAccountsState>
switch (change) {
case AccountRepositoryChange.localAccounts:
emit(_accountRepository.getLocalAccounts());
break;
// Ignore these
case AccountRepositoryChange.userLogins:
case AccountRepositoryChange.activeLocalAccount:

View file

@ -15,6 +15,9 @@ import '../../notifications/notifications.dart';
import '../../proto/proto.dart' as proto;
import '../account_manager.dart';
const _kAccountRecordSubscriptionListenKey =
'accountRecordSubscriptionListenKey';
class PerAccountCollectionCubit extends Cubit<PerAccountCollectionState> {
PerAccountCollectionCubit({
required Locator locator,
@ -32,6 +35,7 @@ class PerAccountCollectionCubit extends Cubit<PerAccountCollectionState> {
await _processor.close();
await accountInfoCubit.close();
await _accountRecordSubscription?.cancel();
await serialFutureClose((this, _kAccountRecordSubscriptionListenKey));
await accountRecordCubit?.close();
await activeSingleContactChatBlocMapCubitUpdater.close();
@ -83,7 +87,7 @@ class PerAccountCollectionCubit extends Cubit<PerAccountCollectionState> {
accountRecordCubit = null;
// Update state to 'loading'
nextState = _updateAccountRecordState(nextState, null);
nextState = await _updateAccountRecordState(nextState, null);
emit(nextState);
} else {
///////////////// Logged in ///////////////////
@ -95,20 +99,22 @@ class PerAccountCollectionCubit extends Cubit<PerAccountCollectionState> {
// Update state to value
nextState =
_updateAccountRecordState(nextState, accountRecordCubit!.state);
await _updateAccountRecordState(nextState, accountRecordCubit!.state);
emit(nextState);
// Subscribe AccountRecordCubit
_accountRecordSubscription ??=
accountRecordCubit!.stream.listen((avAccountRecordState) {
emit(_updateAccountRecordState(state, avAccountRecordState));
serialFuture((this, _kAccountRecordSubscriptionListenKey), () async {
emit(await _updateAccountRecordState(state, avAccountRecordState));
});
});
}
}
PerAccountCollectionState _updateAccountRecordState(
Future<PerAccountCollectionState> _updateAccountRecordState(
PerAccountCollectionState prevState,
AsyncValue<AccountRecordState>? avAccountRecordState) {
AsyncValue<AccountRecordState>? avAccountRecordState) async {
// Get next state
final nextState =
prevState.copyWith(avAccountRecordState: avAccountRecordState);
@ -121,8 +127,8 @@ class PerAccountCollectionCubit extends Cubit<PerAccountCollectionState> {
.avAccountRecordState?.asData?.value.contactInvitationRecords
.toVeilid();
final contactInvitationListCubit = contactInvitationListCubitUpdater.update(
accountInfo.userLogin == null ||
final contactInvitationListCubit = await contactInvitationListCubitUpdater
.update(accountInfo.userLogin == null ||
contactInvitationListRecordPointer == null
? null
: (accountInfo, contactInvitationListRecordPointer));
@ -131,34 +137,35 @@ class PerAccountCollectionCubit extends Cubit<PerAccountCollectionState> {
final contactListRecordPointer =
nextState.avAccountRecordState?.asData?.value.contactList.toVeilid();
final contactListCubit = contactListCubitUpdater.update(
final contactListCubit = await contactListCubitUpdater.update(
accountInfo.userLogin == null || contactListRecordPointer == null
? null
: (accountInfo, contactListRecordPointer));
// WaitingInvitationsBlocMapCubit
final waitingInvitationsBlocMapCubit = waitingInvitationsBlocMapCubitUpdater
.update(accountInfo.userLogin == null ||
contactInvitationListCubit == null ||
contactListCubit == null
? null
: (
accountInfo,
accountRecordCubit!,
contactInvitationListCubit,
contactListCubit,
_locator<NotificationsCubit>(),
));
final waitingInvitationsBlocMapCubit =
await waitingInvitationsBlocMapCubitUpdater.update(
accountInfo.userLogin == null ||
contactInvitationListCubit == null ||
contactListCubit == null
? null
: (
accountInfo,
accountRecordCubit!,
contactInvitationListCubit,
contactListCubit,
_locator<NotificationsCubit>(),
));
// ActiveChatCubit
final activeChatCubit = activeChatCubitUpdater
final activeChatCubit = await activeChatCubitUpdater
.update((accountInfo.userLogin == null) ? null : true);
// ChatListCubit
final chatListRecordPointer =
nextState.avAccountRecordState?.asData?.value.chatList.toVeilid();
final chatListCubit = chatListCubitUpdater.update(
final chatListCubit = await chatListCubitUpdater.update(
accountInfo.userLogin == null ||
chatListRecordPointer == null ||
activeChatCubit == null
@ -167,7 +174,7 @@ class PerAccountCollectionCubit extends Cubit<PerAccountCollectionState> {
// ActiveConversationsBlocMapCubit
final activeConversationsBlocMapCubit =
activeConversationsBlocMapCubitUpdater.update(
await activeConversationsBlocMapCubitUpdater.update(
accountRecordCubit == null ||
chatListCubit == null ||
contactListCubit == null
@ -181,7 +188,7 @@ class PerAccountCollectionCubit extends Cubit<PerAccountCollectionState> {
// ActiveSingleContactChatBlocMapCubit
final activeSingleContactChatBlocMapCubit =
activeSingleContactChatBlocMapCubitUpdater.update(
await activeSingleContactChatBlocMapCubitUpdater.update(
accountInfo.userLogin == null ||
activeConversationsBlocMapCubit == null
? null

View file

@ -17,7 +17,6 @@ class UserLoginsCubit extends Cubit<UserLoginsState> {
switch (change) {
case AccountRepositoryChange.userLogins:
emit(_accountRepository.getUserLogins());
break;
// Ignore these
case AccountRepositoryChange.localAccounts:
case AccountRepositoryChange.activeLocalAccount:

View file

@ -61,6 +61,13 @@ class _EditAccountPageState extends WindowSetupState<EditAccountPage> {
);
Future<void> _onRemoveAccount() async {
// dismiss the keyboard by unfocusing the textfield
FocusScope.of(context).unfocus();
await asyncSleep(const Duration(milliseconds: 250));
if (!mounted) {
return;
}
final confirmed = await StyledDialog.show<bool>(
context: context,
title: translate('edit_account_page.remove_account_confirm'),
@ -87,10 +94,7 @@ class _EditAccountPageState extends WindowSetupState<EditAccountPage> {
]))
]).paddingAll(24)
]));
if (confirmed != null && confirmed && mounted) {
// dismiss the keyboard by unfocusing the textfield
FocusScope.of(context).unfocus();
if (confirmed != null && confirmed) {
try {
setState(() {
_isInAsyncCall = true;
@ -125,6 +129,13 @@ class _EditAccountPageState extends WindowSetupState<EditAccountPage> {
}
Future<void> _onDestroyAccount() async {
// dismiss the keyboard by unfocusing the textfield
FocusScope.of(context).unfocus();
await asyncSleep(const Duration(milliseconds: 250));
if (!mounted) {
return;
}
final confirmed = await StyledDialog.show<bool>(
context: context,
title: translate('edit_account_page.destroy_account_confirm'),
@ -154,10 +165,7 @@ class _EditAccountPageState extends WindowSetupState<EditAccountPage> {
]))
]).paddingAll(24)
]));
if (confirmed != null && confirmed && mounted) {
// dismiss the keyboard by unfocusing the textfield
FocusScope.of(context).unfocus();
if (confirmed != null && confirmed) {
try {
setState(() {
_isInAsyncCall = true;

View file

@ -282,9 +282,6 @@ class _EditProfileFormState extends State<EditProfileForm> {
FormBuilderCheckbox(
name: EditProfileForm.formFieldAutoAway,
initialValue: _savedValue.autoAway,
side: BorderSide(color: scale.primaryScale.border, width: 2),
checkColor: scale.primaryScale.borderText,
activeColor: scale.primaryScale.border,
title: Text(translate('account.form_auto_away'),
style: textTheme.labelMedium),
onChanged: (v) {