mirror of
https://gitlab.com/veilid/veilidchat.git
synced 2025-05-28 10:42:24 -04:00
checkpoint
This commit is contained in:
parent
3edf2ebb46
commit
c40f835ec5
25 changed files with 378 additions and 312 deletions
|
@ -8,7 +8,8 @@ import '../repository/account_repository.dart';
|
|||
|
||||
class AccountInfoCubit extends Cubit<AccountInfo> {
|
||||
AccountInfoCubit(
|
||||
AccountRepository accountRepository, TypedKey superIdentityRecordKey)
|
||||
{required AccountRepository accountRepository,
|
||||
required TypedKey superIdentityRecordKey})
|
||||
: _accountRepository = accountRepository,
|
||||
super(accountRepository.getAccountInfo(superIdentityRecordKey)!) {
|
||||
// Subscribe to streams
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
export 'account_info_cubit.dart';
|
||||
export 'account_record_cubit.dart';
|
||||
export 'account_records_bloc_map_cubit.dart';
|
||||
export 'active_local_account_cubit.dart';
|
||||
export 'local_accounts_cubit.dart';
|
||||
export 'per_account_collection_bloc_map_cubit.dart';
|
||||
export 'per_account_collection_cubit.dart';
|
||||
export 'user_logins_cubit.dart';
|
||||
|
|
|
@ -8,26 +8,30 @@ import '../../account_manager/account_manager.dart';
|
|||
typedef AccountRecordsBlocMapState
|
||||
= BlocMapState<TypedKey, AsyncValue<AccountRecordState>>;
|
||||
|
||||
/// Map of the logged in user accounts to their AccountRecordCubit
|
||||
/// Map of the logged in user accounts to their PerAccountCollectionCubit
|
||||
/// Ensures there is an single account record cubit for each logged in account
|
||||
class AccountRecordsBlocMapCubit extends BlocMapCubit<TypedKey,
|
||||
AsyncValue<AccountRecordState>, AccountRecordCubit>
|
||||
class PerAccountCollectionBlocMapCubit extends BlocMapCubit<TypedKey,
|
||||
PerAccountCollectionState, PerAccountCollectionCubit>
|
||||
with StateMapFollower<LocalAccountsState, TypedKey, LocalAccount> {
|
||||
AccountRecordsBlocMapCubit(
|
||||
AccountRepository accountRepository, Locator locator)
|
||||
: _accountRepository = accountRepository {
|
||||
PerAccountCollectionBlocMapCubit({
|
||||
required Locator locator,
|
||||
required AccountRepository accountRepository,
|
||||
}) : _locator = locator,
|
||||
_accountRepository = accountRepository {
|
||||
// Follow the local accounts cubit
|
||||
follow(locator<LocalAccountsCubit>());
|
||||
}
|
||||
|
||||
// Add account record cubit
|
||||
Future<void> _addAccountRecordCubit(
|
||||
Future<void> _addPerAccountCollectionCubit(
|
||||
{required TypedKey superIdentityRecordKey}) async =>
|
||||
add(() => MapEntry(
|
||||
superIdentityRecordKey,
|
||||
AccountRecordCubit(
|
||||
accountRepository: _accountRepository,
|
||||
superIdentityRecordKey: superIdentityRecordKey)));
|
||||
PerAccountCollectionCubit(
|
||||
locator: _locator,
|
||||
accountInfoCubit: AccountInfoCubit(
|
||||
accountRepository: _accountRepository,
|
||||
superIdentityRecordKey: superIdentityRecordKey))));
|
||||
|
||||
/// StateFollower /////////////////////////
|
||||
|
||||
|
@ -36,10 +40,11 @@ class AccountRecordsBlocMapCubit extends BlocMapCubit<TypedKey,
|
|||
|
||||
@override
|
||||
Future<void> updateState(TypedKey key, LocalAccount value) async {
|
||||
await _addAccountRecordCubit(
|
||||
await _addPerAccountCollectionCubit(
|
||||
superIdentityRecordKey: value.superIdentity.recordKey);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
final AccountRepository _accountRepository;
|
||||
final Locator _locator;
|
||||
}
|
|
@ -10,6 +10,7 @@ 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 '../account_manager.dart';
|
||||
|
||||
|
@ -30,6 +31,14 @@ class PerAccountCollectionCubit extends Cubit<PerAccountCollectionState> {
|
|||
await _accountRecordSubscription?.cancel();
|
||||
await accountRecordCubit?.close();
|
||||
|
||||
await activeSingleContactChatBlocMapCubitUpdater.close();
|
||||
await activeConversationsBlocMapCubitUpdater.close();
|
||||
await activeChatCubitUpdater.close();
|
||||
await waitingInvitationsBlocMapCubitUpdater.close();
|
||||
await chatListCubitUpdater.close();
|
||||
await contactListCubitUpdater.close();
|
||||
await contactInvitationListCubitUpdater.close();
|
||||
|
||||
await super.close();
|
||||
}
|
||||
|
||||
|
@ -95,48 +104,72 @@ class PerAccountCollectionCubit extends Cubit<PerAccountCollectionState> {
|
|||
state.copyWith(avAccountRecordState: accountRecordCubit!.state);
|
||||
|
||||
// Get bloc parameters
|
||||
final accountRecordKey = nextState.accountInfo.accountRecordKey;
|
||||
final accountInfo = nextState.accountInfo;
|
||||
|
||||
// ContactInvitationListCubit
|
||||
final contactInvitationListRecordPointer = nextState
|
||||
.avAccountRecordState.asData?.value.contactInvitationRecords
|
||||
.toVeilid();
|
||||
|
||||
contactInvitationListCubitUpdater.update(
|
||||
final contactInvitationListCubit = contactInvitationListCubitUpdater.update(
|
||||
contactInvitationListRecordPointer == null
|
||||
? null
|
||||
: (
|
||||
collectionLocator,
|
||||
accountRecordKey,
|
||||
contactInvitationListRecordPointer
|
||||
));
|
||||
: (accountInfo, contactInvitationListRecordPointer));
|
||||
|
||||
// ContactListCubit
|
||||
final contactListRecordPointer =
|
||||
nextState.avAccountRecordState.asData?.value.contactList.toVeilid();
|
||||
|
||||
contactListCubitUpdater.update(contactListRecordPointer == null
|
||||
? null
|
||||
: (collectionLocator, accountRecordKey, contactListRecordPointer));
|
||||
final contactListCubit = contactListCubitUpdater.update(
|
||||
contactListRecordPointer == null
|
||||
? null
|
||||
: (accountInfo, contactListRecordPointer));
|
||||
|
||||
// WaitingInvitationsBlocMapCubit
|
||||
waitingInvitationsBlocMapCubitUpdater.update(
|
||||
nextState.avAccountRecordState.isData ? collectionLocator : null);
|
||||
contactInvitationListCubit == null
|
||||
? null
|
||||
: (accountInfo, accountRecordCubit!, contactInvitationListCubit));
|
||||
|
||||
// ActiveChatCubit
|
||||
activeChatCubitUpdater
|
||||
final activeChatCubit = activeChatCubitUpdater
|
||||
.update(nextState.avAccountRecordState.isData ? true : null);
|
||||
|
||||
// ChatListCubit
|
||||
final chatListRecordPointer =
|
||||
nextState.avAccountRecordState.asData?.value.chatList.toVeilid();
|
||||
|
||||
chatListCubitUpdater.update(chatListRecordPointer == null
|
||||
? null
|
||||
: (collectionLocator, accountRecordKey, chatListRecordPointer));
|
||||
final chatListCubit = chatListCubitUpdater.update(
|
||||
chatListRecordPointer == null || activeChatCubit == null
|
||||
? null
|
||||
: (accountInfo, chatListRecordPointer, activeChatCubit));
|
||||
|
||||
// ActiveConversationsBlocMapCubit
|
||||
// xxx
|
||||
final activeConversationsBlocMapCubit =
|
||||
activeConversationsBlocMapCubitUpdater.update(
|
||||
accountRecordCubit == null ||
|
||||
chatListCubit == null ||
|
||||
contactListCubit == null
|
||||
? null
|
||||
: (
|
||||
accountInfo,
|
||||
accountRecordCubit!,
|
||||
chatListCubit,
|
||||
contactListCubit
|
||||
));
|
||||
|
||||
// ActiveSingleContactChatBlocMapCubit
|
||||
activeSingleContactChatBlocMapCubitUpdater.update(
|
||||
activeConversationsBlocMapCubit == null ||
|
||||
chatListCubit == null ||
|
||||
contactListCubit == null
|
||||
? null
|
||||
: (
|
||||
accountInfo,
|
||||
activeConversationsBlocMapCubit,
|
||||
chatListCubit,
|
||||
contactListCubit
|
||||
));
|
||||
|
||||
return nextState;
|
||||
}
|
||||
|
@ -163,6 +196,12 @@ class PerAccountCollectionCubit extends Cubit<PerAccountCollectionState> {
|
|||
if (T is ChatListCubit) {
|
||||
return chatListCubitUpdater.bloc! as T;
|
||||
}
|
||||
if (T is ActiveConversationsBlocMapCubit) {
|
||||
return activeConversationsBlocMapCubitUpdater.bloc! as T;
|
||||
}
|
||||
if (T is ActiveSingleContactChatBlocMapCubit) {
|
||||
return activeSingleContactChatBlocMapCubitUpdater.bloc! as T;
|
||||
}
|
||||
return _locator<T>();
|
||||
}
|
||||
|
||||
|
@ -178,32 +217,52 @@ class PerAccountCollectionCubit extends Cubit<PerAccountCollectionState> {
|
|||
StreamSubscription<AsyncValue<AccountRecordState>>?
|
||||
_accountRecordSubscription;
|
||||
final contactInvitationListCubitUpdater = BlocUpdater<
|
||||
ContactInvitationListCubit,
|
||||
(Locator, TypedKey, OwnedDHTRecordPointer)>(
|
||||
ContactInvitationListCubit, (AccountInfo, OwnedDHTRecordPointer)>(
|
||||
create: (params) => ContactInvitationListCubit(
|
||||
locator: params.$1,
|
||||
accountRecordKey: params.$2,
|
||||
contactInvitationListRecordPointer: params.$3,
|
||||
accountInfo: params.$1,
|
||||
contactInvitationListRecordPointer: params.$2,
|
||||
));
|
||||
final contactListCubitUpdater =
|
||||
BlocUpdater<ContactListCubit, (Locator, TypedKey, OwnedDHTRecordPointer)>(
|
||||
BlocUpdater<ContactListCubit, (AccountInfo, OwnedDHTRecordPointer)>(
|
||||
create: (params) => ContactListCubit(
|
||||
locator: params.$1,
|
||||
accountRecordKey: params.$2,
|
||||
contactListRecordPointer: params.$3,
|
||||
));
|
||||
final waitingInvitationsBlocMapCubitUpdater =
|
||||
BlocUpdater<WaitingInvitationsBlocMapCubit, Locator>(
|
||||
create: (params) => WaitingInvitationsBlocMapCubit(
|
||||
locator: params,
|
||||
accountInfo: params.$1,
|
||||
contactListRecordPointer: params.$2,
|
||||
));
|
||||
final waitingInvitationsBlocMapCubitUpdater = BlocUpdater<
|
||||
WaitingInvitationsBlocMapCubit,
|
||||
(AccountInfo, AccountRecordCubit, ContactInvitationListCubit)>(
|
||||
create: (params) => WaitingInvitationsBlocMapCubit(
|
||||
accountInfo: params.$1,
|
||||
accountRecordCubit: params.$2,
|
||||
contactInvitationListCubit: params.$3));
|
||||
final activeChatCubitUpdater =
|
||||
BlocUpdater<ActiveChatCubit, bool>(create: (_) => ActiveChatCubit(null));
|
||||
final chatListCubitUpdater =
|
||||
BlocUpdater<ChatListCubit, (Locator, TypedKey, OwnedDHTRecordPointer)>(
|
||||
create: (params) => ChatListCubit(
|
||||
locator: params.$1,
|
||||
accountRecordKey: params.$2,
|
||||
chatListRecordPointer: params.$3,
|
||||
));
|
||||
final chatListCubitUpdater = BlocUpdater<ChatListCubit,
|
||||
(AccountInfo, OwnedDHTRecordPointer, ActiveChatCubit)>(
|
||||
create: (params) => ChatListCubit(
|
||||
accountInfo: params.$1,
|
||||
chatListRecordPointer: params.$2,
|
||||
activeChatCubit: params.$3));
|
||||
final activeConversationsBlocMapCubitUpdater = BlocUpdater<
|
||||
ActiveConversationsBlocMapCubit,
|
||||
(AccountInfo, AccountRecordCubit, ChatListCubit, ContactListCubit)>(
|
||||
create: (params) => ActiveConversationsBlocMapCubit(
|
||||
accountInfo: params.$1,
|
||||
accountRecordCubit: params.$2,
|
||||
chatListCubit: params.$3,
|
||||
contactListCubit: params.$4));
|
||||
final activeSingleContactChatBlocMapCubitUpdater = BlocUpdater<
|
||||
ActiveSingleContactChatBlocMapCubit,
|
||||
(
|
||||
AccountInfo,
|
||||
ActiveConversationsBlocMapCubit,
|
||||
ChatListCubit,
|
||||
ContactListCubit
|
||||
)>(
|
||||
create: (params) => ActiveSingleContactChatBlocMapCubit(
|
||||
accountInfo: params.$1,
|
||||
activeConversationsBlocMapCubit: params.$2,
|
||||
chatListCubit: params.$3,
|
||||
contactListCubit: params.$4,
|
||||
));
|
||||
}
|
||||
|
|
|
@ -16,20 +16,17 @@ enum AccountInfoStatus {
|
|||
class AccountInfo extends Equatable {
|
||||
const AccountInfo({
|
||||
required this.status,
|
||||
required this.active,
|
||||
required this.localAccount,
|
||||
required this.userLogin,
|
||||
});
|
||||
|
||||
final AccountInfoStatus status;
|
||||
final bool active;
|
||||
final LocalAccount localAccount;
|
||||
final UserLogin? userLogin;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
status,
|
||||
active,
|
||||
localAccount,
|
||||
userLogin,
|
||||
];
|
||||
|
|
|
@ -93,10 +93,6 @@ class AccountRepository {
|
|||
}
|
||||
|
||||
AccountInfo? getAccountInfo(TypedKey superIdentityRecordKey) {
|
||||
// Get active account if we have one
|
||||
final activeLocalAccount = getActiveLocalAccount();
|
||||
final active = superIdentityRecordKey == activeLocalAccount;
|
||||
|
||||
// Get which local account we want to fetch the profile for
|
||||
final localAccount = fetchLocalAccount(superIdentityRecordKey);
|
||||
if (localAccount == null) {
|
||||
|
@ -109,7 +105,6 @@ class AccountRepository {
|
|||
// Account was locked
|
||||
return AccountInfo(
|
||||
status: AccountInfoStatus.accountLocked,
|
||||
active: active,
|
||||
localAccount: localAccount,
|
||||
userLogin: null,
|
||||
);
|
||||
|
@ -118,7 +113,6 @@ class AccountRepository {
|
|||
// Got account, decrypted and decoded
|
||||
return AccountInfo(
|
||||
status: AccountInfoStatus.accountUnlocked,
|
||||
active: active,
|
||||
localAccount: localAccount,
|
||||
userLogin: userLogin,
|
||||
);
|
||||
|
|
|
@ -116,13 +116,13 @@ class _EditAccountPageState extends State<EditAccountPage> {
|
|||
});
|
||||
try {
|
||||
// Look up account cubit for this specific account
|
||||
final accountRecordsCubit =
|
||||
context.read<AccountRecordsBlocMapCubit>();
|
||||
await accountRecordsCubit.operateAsync(
|
||||
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.updateProfile(newProfile);
|
||||
await c.accountRecordCubit!.updateProfile(newProfile);
|
||||
});
|
||||
|
||||
// Update local account profile
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue