checkpoint

This commit is contained in:
Christien Rioux 2024-06-19 11:35:51 -04:00
parent c40f835ec5
commit aea196deb3
7 changed files with 371 additions and 177 deletions

View File

@ -1,12 +1,11 @@
import 'package:async_tools/async_tools.dart';
import 'package:bloc_advanced_tools/bloc_advanced_tools.dart';
import 'package:provider/provider.dart';
import 'package:veilid_support/veilid_support.dart';
import '../../account_manager/account_manager.dart';
typedef AccountRecordsBlocMapState
= BlocMapState<TypedKey, AsyncValue<AccountRecordState>>;
typedef PerAccountCollectionBlocMapState
= BlocMapState<TypedKey, PerAccountCollectionState>;
/// Map of the logged in user accounts to their PerAccountCollectionCubit
/// Ensures there is an single account record cubit for each logged in account

View File

@ -55,11 +55,26 @@ class PerAccountCollectionCubit extends Cubit<PerAccountCollectionState> {
PerAccountCollectionState(
accountInfo: accountInfoCubit.state,
avAccountRecordState: const AsyncValue.loading(),
contactInvitationListCubit: null);
contactInvitationListCubit: null,
accountInfoCubit: null,
accountRecordCubit: null,
contactListCubit: null,
waitingInvitationsBlocMapCubit: null,
activeChatCubit: null,
chatListCubit: null,
activeConversationsBlocMapCubit: null,
activeSingleContactChatBlocMapCubit: null);
Future<void> _followAccountInfoState(AccountInfo accountInfo) async {
// If state hasn't changed just return
if (state.accountInfo == accountInfo) {
return;
}
// Get the next state
var nextState = state.copyWith(accountInfo: accountInfo);
// Update AccountRecordCubit
if (accountInfo.userLogin == null) {
/////////////// Not logged in /////////////////
@ -67,7 +82,7 @@ class PerAccountCollectionCubit extends Cubit<PerAccountCollectionState> {
await _accountRecordSubscription?.cancel();
_accountRecordSubscription = null;
// Update state
// Update state to 'loading'
nextState =
_updateAccountRecordState(nextState, const AsyncValue.loading());
emit(nextState);
@ -78,12 +93,12 @@ class PerAccountCollectionCubit extends Cubit<PerAccountCollectionState> {
} else {
///////////////// Logged in ///////////////////
// AccountRecordCubit
// Create AccountRecordCubit
accountRecordCubit ??= AccountRecordCubit(
localAccount: accountInfo.localAccount,
userLogin: accountInfo.userLogin!);
// Update State
// Update state to value
nextState =
_updateAccountRecordState(nextState, accountRecordCubit!.state);
emit(nextState);
@ -98,17 +113,17 @@ class PerAccountCollectionCubit extends Cubit<PerAccountCollectionState> {
PerAccountCollectionState _updateAccountRecordState(
PerAccountCollectionState prevState,
AsyncValue<AccountRecordState> avAccountRecordState) {
AsyncValue<AccountRecordState>? avAccountRecordState) {
// Get next state
final nextState =
state.copyWith(avAccountRecordState: accountRecordCubit!.state);
state.copyWith(avAccountRecordState: avAccountRecordState);
// Get bloc parameters
final accountInfo = nextState.accountInfo;
// ContactInvitationListCubit
final contactInvitationListRecordPointer = nextState
.avAccountRecordState.asData?.value.contactInvitationRecords
.avAccountRecordState?.asData?.value.contactInvitationRecords
.toVeilid();
final contactInvitationListCubit = contactInvitationListCubitUpdater.update(
@ -118,7 +133,7 @@ class PerAccountCollectionCubit extends Cubit<PerAccountCollectionState> {
// ContactListCubit
final contactListRecordPointer =
nextState.avAccountRecordState.asData?.value.contactList.toVeilid();
nextState.avAccountRecordState?.asData?.value.contactList.toVeilid();
final contactListCubit = contactListCubitUpdater.update(
contactListRecordPointer == null
@ -126,18 +141,18 @@ class PerAccountCollectionCubit extends Cubit<PerAccountCollectionState> {
: (accountInfo, contactListRecordPointer));
// WaitingInvitationsBlocMapCubit
waitingInvitationsBlocMapCubitUpdater.update(
contactInvitationListCubit == null
final waitingInvitationsBlocMapCubit = waitingInvitationsBlocMapCubitUpdater
.update(contactInvitationListCubit == null
? null
: (accountInfo, accountRecordCubit!, contactInvitationListCubit));
// ActiveChatCubit
final activeChatCubit = activeChatCubitUpdater
.update(nextState.avAccountRecordState.isData ? true : null);
final activeChatCubit = activeChatCubitUpdater.update(
(nextState.avAccountRecordState?.isData ?? false) ? true : null);
// ChatListCubit
final chatListRecordPointer =
nextState.avAccountRecordState.asData?.value.chatList.toVeilid();
nextState.avAccountRecordState?.asData?.value.chatList.toVeilid();
final chatListCubit = chatListCubitUpdater.update(
chatListRecordPointer == null || activeChatCubit == null
@ -159,19 +174,31 @@ class PerAccountCollectionCubit extends Cubit<PerAccountCollectionState> {
));
// ActiveSingleContactChatBlocMapCubit
activeSingleContactChatBlocMapCubitUpdater.update(
activeConversationsBlocMapCubit == null ||
chatListCubit == null ||
contactListCubit == null
? null
: (
accountInfo,
activeConversationsBlocMapCubit,
chatListCubit,
contactListCubit
));
final activeSingleContactChatBlocMapCubit =
activeSingleContactChatBlocMapCubitUpdater.update(
activeConversationsBlocMapCubit == null ||
chatListCubit == null ||
contactListCubit == null
? null
: (
accountInfo,
activeConversationsBlocMapCubit,
chatListCubit,
contactListCubit
));
return nextState;
// Update available blocs in our state
return nextState.copyWith(
contactInvitationListCubit: contactInvitationListCubit,
accountInfoCubit: accountInfoCubit,
accountRecordCubit: accountRecordCubit,
contactListCubit: contactListCubit,
waitingInvitationsBlocMapCubit: waitingInvitationsBlocMapCubit,
activeChatCubit: activeChatCubit,
chatListCubit: chatListCubit,
activeConversationsBlocMapCubit: activeConversationsBlocMapCubit,
activeSingleContactChatBlocMapCubit:
activeSingleContactChatBlocMapCubit);
}
T collectionLocator<T>() {

View File

@ -1,7 +1,13 @@
import 'package:async_tools/async_tools.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import '../../../chat/chat.dart';
import '../../../chat_list/chat_list.dart';
import '../../../contact_invitation/contact_invitation.dart';
import '../../../contacts/contacts.dart';
import '../../../conversation/conversation.dart';
import '../../../proto/proto.dart' show Account;
import '../../account_manager.dart';
@ -9,9 +15,45 @@ part 'per_account_collection_state.freezed.dart';
@freezed
class PerAccountCollectionState with _$PerAccountCollectionState {
const factory PerAccountCollectionState(
{required AccountInfo accountInfo,
required AsyncValue<AccountRecordState> avAccountRecordState,
required ContactInvitationListCubit? contactInvitationListCubit}) =
_PerAccountCollectionState;
const factory PerAccountCollectionState({
required AccountInfo accountInfo,
required AsyncValue<AccountRecordState>? avAccountRecordState,
required AccountInfoCubit? accountInfoCubit,
required AccountRecordCubit? accountRecordCubit,
required ContactInvitationListCubit? contactInvitationListCubit,
required ContactListCubit? contactListCubit,
required WaitingInvitationsBlocMapCubit? waitingInvitationsBlocMapCubit,
required ActiveChatCubit? activeChatCubit,
required ChatListCubit? chatListCubit,
required ActiveConversationsBlocMapCubit? activeConversationsBlocMapCubit,
required ActiveSingleContactChatBlocMapCubit?
activeSingleContactChatBlocMapCubit,
}) = _PerAccountCollectionState;
}
extension PerAccountCollectionStateExt on PerAccountCollectionState {
bool get isReady =>
avAccountRecordState != null &&
avAccountRecordState!.isData &&
accountInfoCubit != null &&
accountRecordCubit != null &&
contactInvitationListCubit != null &&
contactListCubit != null &&
waitingInvitationsBlocMapCubit != null &&
activeChatCubit != null &&
chatListCubit != null &&
activeConversationsBlocMapCubit != null &&
activeSingleContactChatBlocMapCubit != null;
Widget provide({required Widget child}) => MultiBlocProvider(providers: [
BlocProvider.value(value: accountInfoCubit!),
BlocProvider.value(value: accountRecordCubit!),
BlocProvider.value(value: contactInvitationListCubit!),
BlocProvider.value(value: contactListCubit!),
BlocProvider.value(value: waitingInvitationsBlocMapCubit!),
BlocProvider.value(value: activeChatCubit!),
BlocProvider.value(value: chatListCubit!),
BlocProvider.value(value: activeConversationsBlocMapCubit!),
BlocProvider.value(value: activeSingleContactChatBlocMapCubit!),
], child: child);
}

View File

@ -17,10 +17,23 @@ final _privateConstructorUsedError = UnsupportedError(
/// @nodoc
mixin _$PerAccountCollectionState {
AccountInfo get accountInfo => throw _privateConstructorUsedError;
AsyncValue<Account> get avAccountRecordState =>
AsyncValue<Account>? get avAccountRecordState =>
throw _privateConstructorUsedError;
AccountInfoCubit? get accountInfoCubit => throw _privateConstructorUsedError;
AccountRecordCubit? get accountRecordCubit =>
throw _privateConstructorUsedError;
ContactInvitationListCubit? get contactInvitationListCubit =>
throw _privateConstructorUsedError;
ContactListCubit? get contactListCubit => throw _privateConstructorUsedError;
WaitingInvitationsBlocMapCubit? get waitingInvitationsBlocMapCubit =>
throw _privateConstructorUsedError;
ActiveChatCubit? get activeChatCubit => throw _privateConstructorUsedError;
ChatListCubit? get chatListCubit => throw _privateConstructorUsedError;
ActiveConversationsBlocMapCubit? get activeConversationsBlocMapCubit =>
throw _privateConstructorUsedError;
ActiveSingleContactChatBlocMapCubit?
get activeSingleContactChatBlocMapCubit =>
throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$PerAccountCollectionStateCopyWith<PerAccountCollectionState> get copyWith =>
@ -35,10 +48,19 @@ abstract class $PerAccountCollectionStateCopyWith<$Res> {
@useResult
$Res call(
{AccountInfo accountInfo,
AsyncValue<Account> avAccountRecordState,
ContactInvitationListCubit? contactInvitationListCubit});
AsyncValue<Account>? avAccountRecordState,
AccountInfoCubit? accountInfoCubit,
AccountRecordCubit? accountRecordCubit,
ContactInvitationListCubit? contactInvitationListCubit,
ContactListCubit? contactListCubit,
WaitingInvitationsBlocMapCubit? waitingInvitationsBlocMapCubit,
ActiveChatCubit? activeChatCubit,
ChatListCubit? chatListCubit,
ActiveConversationsBlocMapCubit? activeConversationsBlocMapCubit,
ActiveSingleContactChatBlocMapCubit?
activeSingleContactChatBlocMapCubit});
$AsyncValueCopyWith<Account, $Res> get avAccountRecordState;
$AsyncValueCopyWith<Account, $Res>? get avAccountRecordState;
}
/// @nodoc
@ -56,29 +78,75 @@ class _$PerAccountCollectionStateCopyWithImpl<$Res,
@override
$Res call({
Object? accountInfo = null,
Object? avAccountRecordState = null,
Object? avAccountRecordState = freezed,
Object? accountInfoCubit = freezed,
Object? accountRecordCubit = freezed,
Object? contactInvitationListCubit = freezed,
Object? contactListCubit = freezed,
Object? waitingInvitationsBlocMapCubit = freezed,
Object? activeChatCubit = freezed,
Object? chatListCubit = freezed,
Object? activeConversationsBlocMapCubit = freezed,
Object? activeSingleContactChatBlocMapCubit = freezed,
}) {
return _then(_value.copyWith(
accountInfo: null == accountInfo
? _value.accountInfo
: accountInfo // ignore: cast_nullable_to_non_nullable
as AccountInfo,
avAccountRecordState: null == avAccountRecordState
avAccountRecordState: freezed == avAccountRecordState
? _value.avAccountRecordState
: avAccountRecordState // ignore: cast_nullable_to_non_nullable
as AsyncValue<Account>,
as AsyncValue<Account>?,
accountInfoCubit: freezed == accountInfoCubit
? _value.accountInfoCubit
: accountInfoCubit // ignore: cast_nullable_to_non_nullable
as AccountInfoCubit?,
accountRecordCubit: freezed == accountRecordCubit
? _value.accountRecordCubit
: accountRecordCubit // ignore: cast_nullable_to_non_nullable
as AccountRecordCubit?,
contactInvitationListCubit: freezed == contactInvitationListCubit
? _value.contactInvitationListCubit
: contactInvitationListCubit // ignore: cast_nullable_to_non_nullable
as ContactInvitationListCubit?,
contactListCubit: freezed == contactListCubit
? _value.contactListCubit
: contactListCubit // ignore: cast_nullable_to_non_nullable
as ContactListCubit?,
waitingInvitationsBlocMapCubit: freezed == waitingInvitationsBlocMapCubit
? _value.waitingInvitationsBlocMapCubit
: waitingInvitationsBlocMapCubit // ignore: cast_nullable_to_non_nullable
as WaitingInvitationsBlocMapCubit?,
activeChatCubit: freezed == activeChatCubit
? _value.activeChatCubit
: activeChatCubit // ignore: cast_nullable_to_non_nullable
as ActiveChatCubit?,
chatListCubit: freezed == chatListCubit
? _value.chatListCubit
: chatListCubit // ignore: cast_nullable_to_non_nullable
as ChatListCubit?,
activeConversationsBlocMapCubit: freezed ==
activeConversationsBlocMapCubit
? _value.activeConversationsBlocMapCubit
: activeConversationsBlocMapCubit // ignore: cast_nullable_to_non_nullable
as ActiveConversationsBlocMapCubit?,
activeSingleContactChatBlocMapCubit: freezed ==
activeSingleContactChatBlocMapCubit
? _value.activeSingleContactChatBlocMapCubit
: activeSingleContactChatBlocMapCubit // ignore: cast_nullable_to_non_nullable
as ActiveSingleContactChatBlocMapCubit?,
) as $Val);
}
@override
@pragma('vm:prefer-inline')
$AsyncValueCopyWith<Account, $Res> get avAccountRecordState {
return $AsyncValueCopyWith<Account, $Res>(_value.avAccountRecordState,
$AsyncValueCopyWith<Account, $Res>? get avAccountRecordState {
if (_value.avAccountRecordState == null) {
return null;
}
return $AsyncValueCopyWith<Account, $Res>(_value.avAccountRecordState!,
(value) {
return _then(_value.copyWith(avAccountRecordState: value) as $Val);
});
@ -96,11 +164,20 @@ abstract class _$$PerAccountCollectionStateImplCopyWith<$Res>
@useResult
$Res call(
{AccountInfo accountInfo,
AsyncValue<Account> avAccountRecordState,
ContactInvitationListCubit? contactInvitationListCubit});
AsyncValue<Account>? avAccountRecordState,
AccountInfoCubit? accountInfoCubit,
AccountRecordCubit? accountRecordCubit,
ContactInvitationListCubit? contactInvitationListCubit,
ContactListCubit? contactListCubit,
WaitingInvitationsBlocMapCubit? waitingInvitationsBlocMapCubit,
ActiveChatCubit? activeChatCubit,
ChatListCubit? chatListCubit,
ActiveConversationsBlocMapCubit? activeConversationsBlocMapCubit,
ActiveSingleContactChatBlocMapCubit?
activeSingleContactChatBlocMapCubit});
@override
$AsyncValueCopyWith<Account, $Res> get avAccountRecordState;
$AsyncValueCopyWith<Account, $Res>? get avAccountRecordState;
}
/// @nodoc
@ -117,22 +194,64 @@ class __$$PerAccountCollectionStateImplCopyWithImpl<$Res>
@override
$Res call({
Object? accountInfo = null,
Object? avAccountRecordState = null,
Object? avAccountRecordState = freezed,
Object? accountInfoCubit = freezed,
Object? accountRecordCubit = freezed,
Object? contactInvitationListCubit = freezed,
Object? contactListCubit = freezed,
Object? waitingInvitationsBlocMapCubit = freezed,
Object? activeChatCubit = freezed,
Object? chatListCubit = freezed,
Object? activeConversationsBlocMapCubit = freezed,
Object? activeSingleContactChatBlocMapCubit = freezed,
}) {
return _then(_$PerAccountCollectionStateImpl(
accountInfo: null == accountInfo
? _value.accountInfo
: accountInfo // ignore: cast_nullable_to_non_nullable
as AccountInfo,
avAccountRecordState: null == avAccountRecordState
avAccountRecordState: freezed == avAccountRecordState
? _value.avAccountRecordState
: avAccountRecordState // ignore: cast_nullable_to_non_nullable
as AsyncValue<Account>,
as AsyncValue<Account>?,
accountInfoCubit: freezed == accountInfoCubit
? _value.accountInfoCubit
: accountInfoCubit // ignore: cast_nullable_to_non_nullable
as AccountInfoCubit?,
accountRecordCubit: freezed == accountRecordCubit
? _value.accountRecordCubit
: accountRecordCubit // ignore: cast_nullable_to_non_nullable
as AccountRecordCubit?,
contactInvitationListCubit: freezed == contactInvitationListCubit
? _value.contactInvitationListCubit
: contactInvitationListCubit // ignore: cast_nullable_to_non_nullable
as ContactInvitationListCubit?,
contactListCubit: freezed == contactListCubit
? _value.contactListCubit
: contactListCubit // ignore: cast_nullable_to_non_nullable
as ContactListCubit?,
waitingInvitationsBlocMapCubit: freezed == waitingInvitationsBlocMapCubit
? _value.waitingInvitationsBlocMapCubit
: waitingInvitationsBlocMapCubit // ignore: cast_nullable_to_non_nullable
as WaitingInvitationsBlocMapCubit?,
activeChatCubit: freezed == activeChatCubit
? _value.activeChatCubit
: activeChatCubit // ignore: cast_nullable_to_non_nullable
as ActiveChatCubit?,
chatListCubit: freezed == chatListCubit
? _value.chatListCubit
: chatListCubit // ignore: cast_nullable_to_non_nullable
as ChatListCubit?,
activeConversationsBlocMapCubit: freezed ==
activeConversationsBlocMapCubit
? _value.activeConversationsBlocMapCubit
: activeConversationsBlocMapCubit // ignore: cast_nullable_to_non_nullable
as ActiveConversationsBlocMapCubit?,
activeSingleContactChatBlocMapCubit: freezed ==
activeSingleContactChatBlocMapCubit
? _value.activeSingleContactChatBlocMapCubit
: activeSingleContactChatBlocMapCubit // ignore: cast_nullable_to_non_nullable
as ActiveSingleContactChatBlocMapCubit?,
));
}
}
@ -143,18 +262,43 @@ class _$PerAccountCollectionStateImpl implements _PerAccountCollectionState {
const _$PerAccountCollectionStateImpl(
{required this.accountInfo,
required this.avAccountRecordState,
required this.contactInvitationListCubit});
required this.accountInfoCubit,
required this.accountRecordCubit,
required this.contactInvitationListCubit,
required this.contactListCubit,
required this.waitingInvitationsBlocMapCubit,
required this.activeChatCubit,
required this.chatListCubit,
required this.activeConversationsBlocMapCubit,
required this.activeSingleContactChatBlocMapCubit});
@override
final AccountInfo accountInfo;
@override
final AsyncValue<Account> avAccountRecordState;
final AsyncValue<Account>? avAccountRecordState;
@override
final AccountInfoCubit? accountInfoCubit;
@override
final AccountRecordCubit? accountRecordCubit;
@override
final ContactInvitationListCubit? contactInvitationListCubit;
@override
final ContactListCubit? contactListCubit;
@override
final WaitingInvitationsBlocMapCubit? waitingInvitationsBlocMapCubit;
@override
final ActiveChatCubit? activeChatCubit;
@override
final ChatListCubit? chatListCubit;
@override
final ActiveConversationsBlocMapCubit? activeConversationsBlocMapCubit;
@override
final ActiveSingleContactChatBlocMapCubit?
activeSingleContactChatBlocMapCubit;
@override
String toString() {
return 'PerAccountCollectionState(accountInfo: $accountInfo, avAccountRecordState: $avAccountRecordState, contactInvitationListCubit: $contactInvitationListCubit)';
return 'PerAccountCollectionState(accountInfo: $accountInfo, avAccountRecordState: $avAccountRecordState, accountInfoCubit: $accountInfoCubit, accountRecordCubit: $accountRecordCubit, contactInvitationListCubit: $contactInvitationListCubit, contactListCubit: $contactListCubit, waitingInvitationsBlocMapCubit: $waitingInvitationsBlocMapCubit, activeChatCubit: $activeChatCubit, chatListCubit: $chatListCubit, activeConversationsBlocMapCubit: $activeConversationsBlocMapCubit, activeSingleContactChatBlocMapCubit: $activeSingleContactChatBlocMapCubit)';
}
@override
@ -166,15 +310,48 @@ class _$PerAccountCollectionStateImpl implements _PerAccountCollectionState {
other.accountInfo == accountInfo) &&
(identical(other.avAccountRecordState, avAccountRecordState) ||
other.avAccountRecordState == avAccountRecordState) &&
(identical(other.accountInfoCubit, accountInfoCubit) ||
other.accountInfoCubit == accountInfoCubit) &&
(identical(other.accountRecordCubit, accountRecordCubit) ||
other.accountRecordCubit == accountRecordCubit) &&
(identical(other.contactInvitationListCubit,
contactInvitationListCubit) ||
other.contactInvitationListCubit ==
contactInvitationListCubit));
contactInvitationListCubit) &&
(identical(other.contactListCubit, contactListCubit) ||
other.contactListCubit == contactListCubit) &&
(identical(other.waitingInvitationsBlocMapCubit,
waitingInvitationsBlocMapCubit) ||
other.waitingInvitationsBlocMapCubit ==
waitingInvitationsBlocMapCubit) &&
(identical(other.activeChatCubit, activeChatCubit) ||
other.activeChatCubit == activeChatCubit) &&
(identical(other.chatListCubit, chatListCubit) ||
other.chatListCubit == chatListCubit) &&
(identical(other.activeConversationsBlocMapCubit,
activeConversationsBlocMapCubit) ||
other.activeConversationsBlocMapCubit ==
activeConversationsBlocMapCubit) &&
(identical(other.activeSingleContactChatBlocMapCubit,
activeSingleContactChatBlocMapCubit) ||
other.activeSingleContactChatBlocMapCubit ==
activeSingleContactChatBlocMapCubit));
}
@override
int get hashCode => Object.hash(runtimeType, accountInfo,
avAccountRecordState, contactInvitationListCubit);
int get hashCode => Object.hash(
runtimeType,
accountInfo,
avAccountRecordState,
accountInfoCubit,
accountRecordCubit,
contactInvitationListCubit,
contactListCubit,
waitingInvitationsBlocMapCubit,
activeChatCubit,
chatListCubit,
activeConversationsBlocMapCubit,
activeSingleContactChatBlocMapCubit);
@JsonKey(ignore: true)
@override
@ -186,18 +363,45 @@ class _$PerAccountCollectionStateImpl implements _PerAccountCollectionState {
abstract class _PerAccountCollectionState implements PerAccountCollectionState {
const factory _PerAccountCollectionState(
{required final AccountInfo accountInfo,
required final AsyncValue<Account> avAccountRecordState,
required final ContactInvitationListCubit?
contactInvitationListCubit}) = _$PerAccountCollectionStateImpl;
{required final AccountInfo accountInfo,
required final AsyncValue<Account>? avAccountRecordState,
required final AccountInfoCubit? accountInfoCubit,
required final AccountRecordCubit? accountRecordCubit,
required final ContactInvitationListCubit? contactInvitationListCubit,
required final ContactListCubit? contactListCubit,
required final WaitingInvitationsBlocMapCubit?
waitingInvitationsBlocMapCubit,
required final ActiveChatCubit? activeChatCubit,
required final ChatListCubit? chatListCubit,
required final ActiveConversationsBlocMapCubit?
activeConversationsBlocMapCubit,
required final ActiveSingleContactChatBlocMapCubit?
activeSingleContactChatBlocMapCubit}) =
_$PerAccountCollectionStateImpl;
@override
AccountInfo get accountInfo;
@override
AsyncValue<Account> get avAccountRecordState;
AsyncValue<Account>? get avAccountRecordState;
@override
AccountInfoCubit? get accountInfoCubit;
@override
AccountRecordCubit? get accountRecordCubit;
@override
ContactInvitationListCubit? get contactInvitationListCubit;
@override
ContactListCubit? get contactListCubit;
@override
WaitingInvitationsBlocMapCubit? get waitingInvitationsBlocMapCubit;
@override
ActiveChatCubit? get activeChatCubit;
@override
ChatListCubit? get chatListCubit;
@override
ActiveConversationsBlocMapCubit? get activeConversationsBlocMapCubit;
@override
ActiveSingleContactChatBlocMapCubit? get activeSingleContactChatBlocMapCubit;
@override
@JsonKey(ignore: true)
_$$PerAccountCollectionStateImplCopyWith<_$PerAccountCollectionStateImpl>
get copyWith => throw _privateConstructorUsedError;

View File

@ -116,14 +116,11 @@ class _EditAccountPageState extends State<EditAccountPage> {
});
try {
// Look up account cubit for this specific account
final perAccountCollectionCubit =
context.read<PerAccountCollectionBlocMapCubit>();
await perAccountCollectionCubit.operateAsync(
widget.superIdentityRecordKey, closure: (c) async {
// Update account profile DHT record
// This triggers ConversationCubits to update
await c.accountRecordCubit!.updateProfile(newProfile);
});
final accountRecordCubit = context.read<AccountRecordCubit>();
// Update account profile DHT record
// This triggers ConversationCubits to update
await accountRecordCubit.updateProfile(newProfile);
// Update local account profile
await AccountRepository.instance.editAccountProfile(

View File

@ -105,7 +105,8 @@ class _DrawerMenuState extends State<DrawerMenu> {
Widget _getAccountList(
{required IList<LocalAccount> localAccounts,
required TypedKey? activeLocalAccount,
required AccountRecordsBlocMapState accountRecords}) {
required PerAccountCollectionBlocMapState
perAccountCollectionBlocMapState}) {
final theme = Theme.of(context);
final scaleScheme = theme.extension<ScaleScheme>()!;
@ -116,11 +117,13 @@ class _DrawerMenuState extends State<DrawerMenu> {
final superIdentityRecordKey = la.superIdentity.recordKey;
// See if this account is logged in
final acctRecord = accountRecords.get(superIdentityRecordKey);
if (acctRecord != null) {
final avAccountRecordState = perAccountCollectionBlocMapState
.get(superIdentityRecordKey)
?.avAccountRecordState;
if (avAccountRecordState != null) {
// Account is logged in
final scale = theme.extension<ScaleScheme>()!.tertiaryScale;
final loggedInAccount = acctRecord.when(
final loggedInAccount = avAccountRecordState.when(
data: (value) => _makeAccountWidget(
name: value.profile.name,
scale: scale,
@ -233,7 +236,7 @@ class _DrawerMenuState extends State<DrawerMenu> {
final scale = theme.extension<ScaleScheme>()!;
//final textTheme = theme.textTheme;
final localAccounts = context.watch<LocalAccountsCubit>().state;
final accountRecords =
final perAccountCollectionBlocMapState =
context.watch<PerAccountCollectionBlocMapCubit>().state;
final activeLocalAccount = context.watch<ActiveLocalAccountCubit>().state;
final gradient = LinearGradient(
@ -278,7 +281,7 @@ class _DrawerMenuState extends State<DrawerMenu> {
_getAccountList(
localAccounts: localAccounts,
activeLocalAccount: activeLocalAccount,
accountRecords: accountRecords),
perAccountCollectionBlocMapState: perAccountCollectionBlocMapState),
_getBottomButtons(),
const Spacer(),
Row(children: [

View File

@ -9,11 +9,8 @@ import 'package:veilid_support/veilid_support.dart';
import '../../account_manager/account_manager.dart';
import '../../chat/chat.dart';
import '../../chat_list/chat_list.dart';
import '../../contact_invitation/contact_invitation.dart';
import '../../contacts/contacts.dart';
import '../../conversation/conversation.dart';
import '../../proto/proto.dart' as proto;
import '../../theme/theme.dart';
import '../../tools/tools.dart';
import 'active_account_page_controller_wrapper.dart';
@ -98,113 +95,39 @@ class HomeScreenState extends State<HomeScreen> {
return const HomeAccountReadyMain();
}
Widget _buildUnlockedAccount(BuildContext context) {
final accountRecordKey = context.select<AccountInfoCubit, TypedKey>(
(c) => c.state.unlockedAccountInfo!.accountRecordKey);
final contactListRecordPointer =
context.select<AccountRecordCubit, OwnedDHTRecordPointer?>(
(c) => c.state.asData?.value.contactList.toVeilid());
final contactInvitationListRecordPointer =
context.select<AccountRecordCubit, OwnedDHTRecordPointer?>(
(c) => c.state.asData?.value.contactInvitationRecords.toVeilid());
final chatListRecordPointer =
context.select<AccountRecordCubit, OwnedDHTRecordPointer?>(
(c) => c.state.asData?.value.chatList.toVeilid());
Widget _buildAccount(BuildContext context, TypedKey superIdentityRecordKey,
PerAccountCollectionState perAccountCollectionState) {
switch (perAccountCollectionState.accountInfo.status) {
case AccountInfoStatus.accountInvalid:
return const HomeAccountInvalid();
case AccountInfoStatus.accountLocked:
return const HomeAccountLocked();
case AccountInfoStatus.accountUnlocked:
// Are we ready to render?
if (!perAccountCollectionState.isReady) {
return waitingPage();
}
if (contactListRecordPointer == null ||
contactInvitationListRecordPointer == null ||
chatListRecordPointer == null) {
return waitingPage();
}
return MultiBlocProvider(
providers: [
// Contact Cubits
BlocProvider(
create: (context) => ContactInvitationListCubit(
locator: context.read,
accountRecordKey: accountRecordKey,
contactInvitationListRecordPointer:
contactInvitationListRecordPointer,
)),
BlocProvider(
create: (context) => ContactListCubit(
locator: context.read,
accountRecordKey: accountRecordKey,
contactListRecordPointer: contactListRecordPointer)),
BlocProvider(
create: (context) => WaitingInvitationsBlocMapCubit(
locator: context.read,
)),
// Chat Cubits
BlocProvider(
create: (context) => ActiveChatCubit(
null,
)),
BlocProvider(
create: (context) => ChatListCubit(
locator: context.read,
accountRecordKey: accountRecordKey,
chatListRecordPointer: chatListRecordPointer)),
// Conversation Cubits
BlocProvider(
create: (context) => ActiveConversationsBlocMapCubit(
locator: context.read,
)),
BlocProvider(
create: (context) => ActiveSingleContactChatBlocMapCubit(
locator: context.read,
)),
],
child: MultiBlocListener(listeners: [
// Re-export all ready blocs to the account display subtree
return perAccountCollectionState.provide(
child: MultiBlocListener(listeners: [
BlocListener<WaitingInvitationsBlocMapCubit,
WaitingInvitationsBlocMapState>(
listener: _invitationStatusListener,
)
], child: Builder(builder: _buildAccountReadyDeviceSpecific)));
}
}
Widget _buildAccount(BuildContext context, TypedKey superIdentityRecordKey,
PerAccountCollectionCubit perAccountCollectionCubit) =>
BlocBuilder<PerAccountCollectionCubit, PerAccountCollectionState>(
key: ValueKey(superIdentityRecordKey),
bloc: perAccountCollectionCubit,
builder: (context, state) {
switch (state.accountInfo.status) {
case AccountInfoStatus.accountInvalid:
return const HomeAccountInvalid();
case AccountInfoStatus.accountLocked:
return const HomeAccountLocked();
case AccountInfoStatus.accountUnlocked:
// Get the current active account record cubit
final activeAccountRecordCubit = context.select<
PerAccountCollectionBlocMapCubit,
AccountRecordCubit?>(
(c) => c.tryOperate(superIdentityRecordKey,
closure: (x) => x));
if (activeAccountRecordCubit == null) {
return waitingPage();
}
return MultiBlocProvider(providers: [
BlocProvider<AccountRecordCubit>.value(
value: activeAccountRecordCubit),
], child: Builder(builder: _buildUnlockedAccount));
}
});
};
Widget _buildAccountPageView(BuildContext context) {
final localAccounts = context.watch<LocalAccountsCubit>().state;
final activeLocalAccountCubit = context.watch<ActiveLocalAccountCubit>();
final perAccountCollectionBlocMapCubit =
context.watch<PerAccountCollectionBlocMapCubit>();
final activeLocalAccountCubit =
context.watch<ActiveLocalAccountCubit>().state;
final perAccountCollectionBlocMapState =
context.watch<PerAccountCollectionBlocMapCubit>().state;
final activeIndex = localAccounts.indexWhere(
(x) => x.superIdentity.recordKey == activeLocalAccountCubit.state);
(x) => x.superIdentity.recordKey == activeLocalAccountCubit);
if (activeIndex == -1) {
return const HomeNoActive();
}
@ -231,16 +154,15 @@ class HomeScreenState extends State<HomeScreen> {
itemBuilder: (context, index) {
final superIdentityRecordKey =
localAccounts[index].superIdentity.recordKey;
final perAccountCollectionCubit =
perAccountCollectionBlocMapCubit.tryOperate(
superIdentityRecordKey,
closure: (c) => c);
if (perAccountCollectionCubit == null) {
final perAccountCollectionState =
perAccountCollectionBlocMapState
.get(superIdentityRecordKey);
if (perAccountCollectionState == null) {
return HomeAccountMissing(
key: ValueKey(superIdentityRecordKey));
}
return _buildAccount(context, superIdentityRecordKey,
perAccountCollectionCubit);
perAccountCollectionState);
})));
}