mirror of
https://gitlab.com/veilid/veilidchat.git
synced 2025-03-02 03:39:55 -05:00
more refactor
This commit is contained in:
parent
45ab494969
commit
9219e1307e
@ -1,4 +1,4 @@
|
|||||||
export 'cubit/cubit.dart';
|
export 'cubits/cubits.dart';
|
||||||
export 'models/models.dart';
|
export 'models/models.dart';
|
||||||
export 'repository/repository.dart';
|
export 'repository/repository.dart';
|
||||||
export 'views/views.dart';
|
export 'views/views.dart';
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
part of 'active_user_login_cubit.dart';
|
|
||||||
|
|
||||||
typedef ActiveUserLoginState = TypedKey?;
|
|
@ -1,4 +0,0 @@
|
|||||||
export 'account_record_cubit.dart';
|
|
||||||
export 'active_user_login_cubit/active_user_login_cubit.dart';
|
|
||||||
export 'local_accounts_cubit/local_accounts_cubit.dart';
|
|
||||||
export 'user_logins_cubit/user_logins_cubit.dart';
|
|
@ -1,14 +0,0 @@
|
|||||||
part of 'local_accounts_cubit.dart';
|
|
||||||
|
|
||||||
typedef LocalAccountsState = IList<LocalAccount>;
|
|
||||||
|
|
||||||
extension LocalAccountsStateExt on LocalAccountsState {
|
|
||||||
LocalAccount? fetchLocalAccount({required TypedKey accountMasterRecordKey}) {
|
|
||||||
final idx = indexWhere(
|
|
||||||
(e) => e.identityMaster.masterRecordKey == accountMasterRecordKey);
|
|
||||||
if (idx == -1) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return this[idx];
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
part of 'user_logins_cubit.dart';
|
|
||||||
|
|
||||||
typedef UserLoginsState = IList<UserLogin>;
|
|
||||||
|
|
||||||
extension UserLoginsStateExt on UserLoginsState {
|
|
||||||
UserLogin? fetchUserLogin({required TypedKey accountMasterRecordKey}) {
|
|
||||||
final idx =
|
|
||||||
indexWhere((e) => e.accountMasterRecordKey == accountMasterRecordKey);
|
|
||||||
if (idx == -1) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return this[idx];
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,12 +3,10 @@ import 'dart:async';
|
|||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:veilid_support/veilid_support.dart';
|
import 'package:veilid_support/veilid_support.dart';
|
||||||
|
|
||||||
import '../../repository/account_repository/account_repository.dart';
|
import '../repository/account_repository/account_repository.dart';
|
||||||
|
|
||||||
part 'active_user_login_state.dart';
|
class ActiveLocalAccountCubit extends Cubit<TypedKey?> {
|
||||||
|
ActiveLocalAccountCubit(AccountRepository accountRepository)
|
||||||
class ActiveUserLoginCubit extends Cubit<ActiveUserLoginState> {
|
|
||||||
ActiveUserLoginCubit(AccountRepository accountRepository)
|
|
||||||
: _accountRepository = accountRepository,
|
: _accountRepository = accountRepository,
|
||||||
super(null) {
|
super(null) {
|
||||||
// Subscribe to streams
|
// Subscribe to streams
|
||||||
@ -18,8 +16,8 @@ class ActiveUserLoginCubit extends Cubit<ActiveUserLoginState> {
|
|||||||
void _initAccountRepositorySubscription() {
|
void _initAccountRepositorySubscription() {
|
||||||
_accountRepositorySubscription = _accountRepository.stream.listen((change) {
|
_accountRepositorySubscription = _accountRepository.stream.listen((change) {
|
||||||
switch (change) {
|
switch (change) {
|
||||||
case AccountRepositoryChange.activeUserLogin:
|
case AccountRepositoryChange.activeLocalAccount:
|
||||||
emit(_accountRepository.getActiveUserLogin());
|
emit(_accountRepository.getActiveLocalAccount());
|
||||||
break;
|
break;
|
||||||
// Ignore these
|
// Ignore these
|
||||||
case AccountRepositoryChange.localAccounts:
|
case AccountRepositoryChange.localAccounts:
|
4
lib/account_manager/cubits/cubits.dart
Normal file
4
lib/account_manager/cubits/cubits.dart
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export 'account_record_cubit.dart';
|
||||||
|
export 'active_local_account_cubit.dart';
|
||||||
|
export 'local_accounts_cubit.dart';
|
||||||
|
export 'user_logins_cubit.dart';
|
@ -2,17 +2,14 @@ import 'dart:async';
|
|||||||
|
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
|
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
|
||||||
import 'package:veilid_support/veilid_support.dart';
|
|
||||||
|
|
||||||
import '../../models/models.dart';
|
import '../models/models.dart';
|
||||||
import '../../repository/account_repository/account_repository.dart';
|
import '../repository/account_repository/account_repository.dart';
|
||||||
|
|
||||||
part 'local_accounts_state.dart';
|
class LocalAccountsCubit extends Cubit<IList<LocalAccount>> {
|
||||||
|
|
||||||
class LocalAccountsCubit extends Cubit<LocalAccountsState> {
|
|
||||||
LocalAccountsCubit(AccountRepository accountRepository)
|
LocalAccountsCubit(AccountRepository accountRepository)
|
||||||
: _accountRepository = accountRepository,
|
: _accountRepository = accountRepository,
|
||||||
super(LocalAccountsState()) {
|
super(IList<LocalAccount>()) {
|
||||||
// Subscribe to streams
|
// Subscribe to streams
|
||||||
_initAccountRepositorySubscription();
|
_initAccountRepositorySubscription();
|
||||||
}
|
}
|
||||||
@ -25,7 +22,7 @@ class LocalAccountsCubit extends Cubit<LocalAccountsState> {
|
|||||||
break;
|
break;
|
||||||
// Ignore these
|
// Ignore these
|
||||||
case AccountRepositoryChange.userLogins:
|
case AccountRepositoryChange.userLogins:
|
||||||
case AccountRepositoryChange.activeUserLogin:
|
case AccountRepositoryChange.activeLocalAccount:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
@ -2,17 +2,14 @@ import 'dart:async';
|
|||||||
|
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
|
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
|
||||||
import 'package:veilid_support/veilid_support.dart';
|
|
||||||
|
|
||||||
import '../../models/models.dart';
|
import '../models/models.dart';
|
||||||
import '../../repository/account_repository/account_repository.dart';
|
import '../repository/account_repository/account_repository.dart';
|
||||||
|
|
||||||
part 'user_logins_state.dart';
|
class UserLoginsCubit extends Cubit<IList<UserLogin>> {
|
||||||
|
|
||||||
class UserLoginsCubit extends Cubit<UserLoginsState> {
|
|
||||||
UserLoginsCubit(AccountRepository accountRepository)
|
UserLoginsCubit(AccountRepository accountRepository)
|
||||||
: _accountRepository = accountRepository,
|
: _accountRepository = accountRepository,
|
||||||
super(UserLoginsState()) {
|
super(IList<UserLogin>()) {
|
||||||
// Subscribe to streams
|
// Subscribe to streams
|
||||||
_initAccountRepositorySubscription();
|
_initAccountRepositorySubscription();
|
||||||
}
|
}
|
||||||
@ -25,7 +22,7 @@ class UserLoginsCubit extends Cubit<UserLoginsState> {
|
|||||||
break;
|
break;
|
||||||
// Ignore these
|
// Ignore these
|
||||||
case AccountRepositoryChange.localAccounts:
|
case AccountRepositoryChange.localAccounts:
|
||||||
case AccountRepositoryChange.activeUserLogin:
|
case AccountRepositoryChange.activeLocalAccount:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
@ -6,16 +6,16 @@ import 'package:veilid_support/veilid_support.dart';
|
|||||||
import '../../../../proto/proto.dart' as proto;
|
import '../../../../proto/proto.dart' as proto;
|
||||||
import '../../../tools/tools.dart';
|
import '../../../tools/tools.dart';
|
||||||
import '../../models/models.dart';
|
import '../../models/models.dart';
|
||||||
import 'active_logins.dart';
|
|
||||||
|
|
||||||
const String veilidChatAccountKey = 'com.veilid.veilidchat';
|
const String veilidChatAccountKey = 'com.veilid.veilidchat';
|
||||||
|
|
||||||
enum AccountRepositoryChange { localAccounts, userLogins, activeUserLogin }
|
enum AccountRepositoryChange { localAccounts, userLogins, activeLocalAccount }
|
||||||
|
|
||||||
class AccountRepository {
|
class AccountRepository {
|
||||||
AccountRepository._()
|
AccountRepository._()
|
||||||
: _localAccounts = _initLocalAccounts(),
|
: _localAccounts = _initLocalAccounts(),
|
||||||
_activeLogins = _initActiveLogins(),
|
_userLogins = _initUserLogins(),
|
||||||
|
_activeLocalAccount = _initActiveAccount(),
|
||||||
_streamController =
|
_streamController =
|
||||||
StreamController<AccountRepositoryChange>.broadcast();
|
StreamController<AccountRepositoryChange>.broadcast();
|
||||||
|
|
||||||
@ -28,16 +28,23 @@ class AccountRepository {
|
|||||||
: IList<LocalAccount>(),
|
: IList<LocalAccount>(),
|
||||||
valueToJson: (val) => val.toJson((la) => la.toJson()));
|
valueToJson: (val) => val.toJson((la) => la.toJson()));
|
||||||
|
|
||||||
static TableDBValue<ActiveLogins> _initActiveLogins() => TableDBValue(
|
static TableDBValue<IList<UserLogin>> _initUserLogins() => TableDBValue(
|
||||||
tableName: 'local_account_manager',
|
tableName: 'local_account_manager',
|
||||||
tableKeyName: 'active_logins',
|
tableKeyName: 'user_logins',
|
||||||
valueFromJson: (obj) => obj != null
|
valueFromJson: (obj) => obj != null
|
||||||
? ActiveLogins.fromJson(obj as Map<String, dynamic>)
|
? IList<UserLogin>.fromJson(obj, genericFromJson(UserLogin.fromJson))
|
||||||
: ActiveLogins.empty(),
|
: IList<UserLogin>(),
|
||||||
valueToJson: (val) => val.toJson());
|
valueToJson: (val) => val.toJson((la) => la.toJson()));
|
||||||
|
|
||||||
|
static TableDBValue<TypedKey?> _initActiveAccount() => TableDBValue(
|
||||||
|
tableName: 'local_account_manager',
|
||||||
|
tableKeyName: 'active_local_account',
|
||||||
|
valueFromJson: (obj) => obj == null ? null : TypedKey.fromJson(obj),
|
||||||
|
valueToJson: (val) => val?.toJson());
|
||||||
|
|
||||||
final TableDBValue<IList<LocalAccount>> _localAccounts;
|
final TableDBValue<IList<LocalAccount>> _localAccounts;
|
||||||
final TableDBValue<ActiveLogins> _activeLogins;
|
final TableDBValue<IList<UserLogin>> _userLogins;
|
||||||
|
final TableDBValue<TypedKey?> _activeLocalAccount;
|
||||||
final StreamController<AccountRepositoryChange> _streamController;
|
final StreamController<AccountRepositoryChange> _streamController;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
@ -47,7 +54,8 @@ class AccountRepository {
|
|||||||
|
|
||||||
Future<void> init() async {
|
Future<void> init() async {
|
||||||
await _localAccounts.load();
|
await _localAccounts.load();
|
||||||
await _activeLogins.load();
|
await _userLogins.load();
|
||||||
|
await _activeLocalAccount.load();
|
||||||
await _openLoggedInDHTRecords();
|
await _openLoggedInDHTRecords();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,10 +67,16 @@ class AccountRepository {
|
|||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
/// Selectors
|
/// Selectors
|
||||||
IList<LocalAccount> getLocalAccounts() => _localAccounts.requireValue;
|
IList<LocalAccount> getLocalAccounts() => _localAccounts.requireValue;
|
||||||
IList<UserLogin> getUserLogins() => _activeLogins.requireValue.userLogins;
|
TypedKey? getActiveLocalAccount() => _activeLocalAccount.requireValue;
|
||||||
TypedKey? getActiveUserLogin() => _activeLogins.requireValue.activeUserLogin;
|
IList<UserLogin> getUserLogins() => _userLogins.requireValue;
|
||||||
|
UserLogin? getActiveUserLogin() {
|
||||||
|
final activeLocalAccount = _activeLocalAccount.requireValue;
|
||||||
|
return activeLocalAccount == null
|
||||||
|
? null
|
||||||
|
: fetchUserLogin(activeLocalAccount);
|
||||||
|
}
|
||||||
|
|
||||||
LocalAccount? fetchLocalAccount({required TypedKey accountMasterRecordKey}) {
|
LocalAccount? fetchLocalAccount(TypedKey accountMasterRecordKey) {
|
||||||
final localAccounts = _localAccounts.requireValue;
|
final localAccounts = _localAccounts.requireValue;
|
||||||
final idx = localAccounts.indexWhere(
|
final idx = localAccounts.indexWhere(
|
||||||
(e) => e.identityMaster.masterRecordKey == accountMasterRecordKey);
|
(e) => e.identityMaster.masterRecordKey == accountMasterRecordKey);
|
||||||
@ -72,8 +86,8 @@ class AccountRepository {
|
|||||||
return localAccounts[idx];
|
return localAccounts[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
UserLogin? fetchUserLogin({required TypedKey accountMasterRecordKey}) {
|
UserLogin? fetchUserLogin(TypedKey accountMasterRecordKey) {
|
||||||
final userLogins = _activeLogins.requireValue.userLogins;
|
final userLogins = _userLogins.requireValue;
|
||||||
final idx = userLogins
|
final idx = userLogins
|
||||||
.indexWhere((e) => e.accountMasterRecordKey == accountMasterRecordKey);
|
.indexWhere((e) => e.accountMasterRecordKey == accountMasterRecordKey);
|
||||||
if (idx == -1) {
|
if (idx == -1) {
|
||||||
@ -82,34 +96,33 @@ class AccountRepository {
|
|||||||
return userLogins[idx];
|
return userLogins[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
AccountInfo? getAccountInfo({TypedKey? accountMasterRecordKey}) {
|
AccountInfo getAccountInfo(TypedKey? accountMasterRecordKey) {
|
||||||
// Get active user if we have one
|
// Get active account if we have one
|
||||||
|
final activeLocalAccount = getActiveLocalAccount();
|
||||||
if (accountMasterRecordKey == null) {
|
if (accountMasterRecordKey == null) {
|
||||||
final activeUserLogin = getActiveUserLogin();
|
if (activeLocalAccount == null) {
|
||||||
if (activeUserLogin == null) {
|
|
||||||
// No user logged in
|
// No user logged in
|
||||||
return null;
|
return const AccountInfo(
|
||||||
|
status: AccountInfoStatus.noAccount,
|
||||||
|
active: false,
|
||||||
|
activeAccountInfo: null);
|
||||||
}
|
}
|
||||||
accountMasterRecordKey = activeUserLogin;
|
accountMasterRecordKey = activeLocalAccount;
|
||||||
}
|
}
|
||||||
|
final active = accountMasterRecordKey == activeLocalAccount;
|
||||||
|
|
||||||
// Get which local account we want to fetch the profile for
|
// Get which local account we want to fetch the profile for
|
||||||
final localAccount =
|
final localAccount = fetchLocalAccount(accountMasterRecordKey);
|
||||||
fetchLocalAccount(accountMasterRecordKey: accountMasterRecordKey);
|
|
||||||
if (localAccount == null) {
|
if (localAccount == null) {
|
||||||
// Local account does not exist
|
// account does not exist
|
||||||
return const AccountInfo(
|
return AccountInfo(
|
||||||
status: AccountInfoStatus.noAccount,
|
status: AccountInfoStatus.noAccount,
|
||||||
active: false,
|
active: active,
|
||||||
activeAccountInfo: null);
|
activeAccountInfo: null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// See if we've logged into this account or if it is locked
|
// See if we've logged into this account or if it is locked
|
||||||
final activeUserLogin = getActiveUserLogin();
|
final userLogin = fetchUserLogin(accountMasterRecordKey);
|
||||||
final active = activeUserLogin == accountMasterRecordKey;
|
|
||||||
|
|
||||||
final userLogin =
|
|
||||||
fetchUserLogin(accountMasterRecordKey: accountMasterRecordKey);
|
|
||||||
if (userLogin == null) {
|
if (userLogin == null) {
|
||||||
// Account was locked
|
// Account was locked
|
||||||
return AccountInfo(
|
return AccountInfo(
|
||||||
@ -268,22 +281,20 @@ class AccountRepository {
|
|||||||
/// Delete an account from all devices
|
/// Delete an account from all devices
|
||||||
|
|
||||||
Future<void> switchToAccount(TypedKey? accountMasterRecordKey) async {
|
Future<void> switchToAccount(TypedKey? accountMasterRecordKey) async {
|
||||||
final activeLogins = await _activeLogins.get();
|
final activeLocalAccount = await _activeLocalAccount.get();
|
||||||
|
|
||||||
if (activeLogins.activeUserLogin == accountMasterRecordKey) {
|
if (activeLocalAccount == accountMasterRecordKey) {
|
||||||
// Nothing to do
|
// Nothing to do
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (accountMasterRecordKey != null) {
|
if (accountMasterRecordKey != null) {
|
||||||
// Assert the specified record key can be found, will throw if not
|
// Assert the specified record key can be found, will throw if not
|
||||||
final _ = activeLogins.userLogins.firstWhere(
|
final _ = _userLogins.requireValue.firstWhere(
|
||||||
(ul) => ul.accountMasterRecordKey == accountMasterRecordKey);
|
(ul) => ul.accountMasterRecordKey == accountMasterRecordKey);
|
||||||
}
|
}
|
||||||
final newActiveLogins =
|
await _activeLocalAccount.set(accountMasterRecordKey);
|
||||||
activeLogins.copyWith(activeUserLogin: accountMasterRecordKey);
|
_streamController.add(AccountRepositoryChange.activeLocalAccount);
|
||||||
await _activeLogins.set(newActiveLogins);
|
|
||||||
_streamController.add(AccountRepositoryChange.activeUserLogin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> _decryptedLogin(
|
Future<bool> _decryptedLogin(
|
||||||
@ -301,25 +312,25 @@ class AccountRepository {
|
|||||||
identitySecret: identitySecret, accountKey: veilidChatAccountKey);
|
identitySecret: identitySecret, accountKey: veilidChatAccountKey);
|
||||||
|
|
||||||
// Add to user logins and select it
|
// Add to user logins and select it
|
||||||
final activeLogins = await _activeLogins.get();
|
final userLogins = await _userLogins.get();
|
||||||
final now = Veilid.instance.now();
|
final now = Veilid.instance.now();
|
||||||
final newActiveLogins = activeLogins.copyWith(
|
final newUserLogins = userLogins.replaceFirstWhere(
|
||||||
userLogins: activeLogins.userLogins.replaceFirstWhere(
|
(ul) => ul.accountMasterRecordKey == identityMaster.masterRecordKey,
|
||||||
(ul) => ul.accountMasterRecordKey == identityMaster.masterRecordKey,
|
(ul) => ul != null
|
||||||
(ul) => ul != null
|
? ul.copyWith(lastActive: now)
|
||||||
? ul.copyWith(lastActive: now)
|
: UserLogin(
|
||||||
: UserLogin(
|
accountMasterRecordKey: identityMaster.masterRecordKey,
|
||||||
accountMasterRecordKey: identityMaster.masterRecordKey,
|
identitySecret:
|
||||||
identitySecret:
|
TypedSecret(kind: cs.kind(), value: identitySecret),
|
||||||
TypedSecret(kind: cs.kind(), value: identitySecret),
|
accountRecordInfo: accountRecordInfo,
|
||||||
accountRecordInfo: accountRecordInfo,
|
lastActive: now),
|
||||||
lastActive: now),
|
addIfNotFound: true);
|
||||||
addIfNotFound: true),
|
|
||||||
activeUserLogin: identityMaster.masterRecordKey);
|
await _userLogins.set(newUserLogins);
|
||||||
await _activeLogins.set(newActiveLogins);
|
await _activeLocalAccount.set(identityMaster.masterRecordKey);
|
||||||
_streamController
|
_streamController
|
||||||
..add(AccountRepositoryChange.activeUserLogin)
|
..add(AccountRepositoryChange.userLogins)
|
||||||
..add(AccountRepositoryChange.userLogins);
|
..add(AccountRepositoryChange.activeLocalAccount);
|
||||||
|
|
||||||
// Ensure all logins are opened
|
// Ensure all logins are opened
|
||||||
await _openLoggedInDHTRecords();
|
await _openLoggedInDHTRecords();
|
||||||
@ -355,34 +366,31 @@ class AccountRepository {
|
|||||||
|
|
||||||
Future<void> logout(TypedKey? accountMasterRecordKey) async {
|
Future<void> logout(TypedKey? accountMasterRecordKey) async {
|
||||||
// Resolve which user to log out
|
// Resolve which user to log out
|
||||||
final activeLogins = await _activeLogins.get();
|
//final userLogins = await _userLogins.get();
|
||||||
final logoutUser = accountMasterRecordKey ?? activeLogins.activeUserLogin;
|
final activeLocalAccount = await _activeLocalAccount.get();
|
||||||
|
final logoutUser = accountMasterRecordKey ?? activeLocalAccount;
|
||||||
if (logoutUser == null) {
|
if (logoutUser == null) {
|
||||||
log.error('missing user in logout: $accountMasterRecordKey');
|
log.error('missing user in logout: $accountMasterRecordKey');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final logoutUserLogin = fetchUserLogin(accountMasterRecordKey: logoutUser);
|
final logoutUserLogin = fetchUserLogin(logoutUser);
|
||||||
if (logoutUserLogin != null) {
|
if (logoutUserLogin == null) {
|
||||||
// Close DHT records for this account
|
// Already logged out
|
||||||
final pool = DHTRecordPool.instance;
|
return;
|
||||||
final accountRecordKey =
|
|
||||||
logoutUserLogin.accountRecordInfo.accountRecord.recordKey;
|
|
||||||
final accountRecord = pool.getOpenedRecord(accountRecordKey);
|
|
||||||
await accountRecord?.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close DHT records for this account
|
||||||
|
final pool = DHTRecordPool.instance;
|
||||||
|
final accountRecordKey =
|
||||||
|
logoutUserLogin.accountRecordInfo.accountRecord.recordKey;
|
||||||
|
final accountRecord = pool.getOpenedRecord(accountRecordKey);
|
||||||
|
await accountRecord?.close();
|
||||||
|
|
||||||
// Remove user from active logins list
|
// Remove user from active logins list
|
||||||
final newActiveLogins = activeLogins.copyWith(
|
final newUserLogins = (await _userLogins.get())
|
||||||
activeUserLogin: activeLogins.activeUserLogin == logoutUser
|
.removeWhere((ul) => ul.accountMasterRecordKey == logoutUser);
|
||||||
? null
|
await _userLogins.set(newUserLogins);
|
||||||
: activeLogins.activeUserLogin,
|
|
||||||
userLogins: activeLogins.userLogins
|
|
||||||
.removeWhere((ul) => ul.accountMasterRecordKey == logoutUser));
|
|
||||||
await _activeLogins.set(newActiveLogins);
|
|
||||||
if (activeLogins.activeUserLogin == logoutUser) {
|
|
||||||
_streamController.add(AccountRepositoryChange.activeUserLogin);
|
|
||||||
}
|
|
||||||
_streamController.add(AccountRepositoryChange.userLogins);
|
_streamController.add(AccountRepositoryChange.userLogins);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,15 +398,15 @@ class AccountRepository {
|
|||||||
final pool = DHTRecordPool.instance;
|
final pool = DHTRecordPool.instance;
|
||||||
|
|
||||||
// For all user logins if they arent open yet
|
// For all user logins if they arent open yet
|
||||||
final activeLogins = await _activeLogins.get();
|
final userLogins = await _userLogins.get();
|
||||||
for (final userLogin in activeLogins.userLogins) {
|
for (final userLogin in userLogins) {
|
||||||
//// Account record key /////////////////////////////
|
//// Account record key /////////////////////////////
|
||||||
final accountRecordKey =
|
final accountRecordKey =
|
||||||
userLogin.accountRecordInfo.accountRecord.recordKey;
|
userLogin.accountRecordInfo.accountRecord.recordKey;
|
||||||
final existingAccountRecord = pool.getOpenedRecord(accountRecordKey);
|
final existingAccountRecord = pool.getOpenedRecord(accountRecordKey);
|
||||||
if (existingAccountRecord == null) {
|
if (existingAccountRecord == null) {
|
||||||
final localAccount = fetchLocalAccount(
|
final localAccount =
|
||||||
accountMasterRecordKey: userLogin.accountMasterRecordKey);
|
fetchLocalAccount(userLogin.accountMasterRecordKey);
|
||||||
|
|
||||||
// Record not yet open, do it
|
// Record not yet open, do it
|
||||||
final record = await pool.openOwned(
|
final record = await pool.openOwned(
|
||||||
@ -413,8 +421,8 @@ class AccountRepository {
|
|||||||
Future<void> _closeLoggedInDHTRecords() async {
|
Future<void> _closeLoggedInDHTRecords() async {
|
||||||
final pool = DHTRecordPool.instance;
|
final pool = DHTRecordPool.instance;
|
||||||
|
|
||||||
final activeLogins = await _activeLogins.get();
|
final userLogins = await _userLogins.get();
|
||||||
for (final userLogin in activeLogins.userLogins) {
|
for (final userLogin in userLogins) {
|
||||||
//// Account record key /////////////////////////////
|
//// Account record key /////////////////////////////
|
||||||
final accountRecordKey =
|
final accountRecordKey =
|
||||||
userLogin.accountRecordInfo.accountRecord.recordKey;
|
userLogin.accountRecordInfo.accountRecord.recordKey;
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
// Represents a set of user logins and the currently selected account
|
|
||||||
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
|
|
||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
|
||||||
import 'package:veilid_support/veilid_support.dart';
|
|
||||||
|
|
||||||
import '../../models/models.dart';
|
|
||||||
|
|
||||||
part 'active_logins.g.dart';
|
|
||||||
part 'active_logins.freezed.dart';
|
|
||||||
|
|
||||||
@freezed
|
|
||||||
class ActiveLogins with _$ActiveLogins {
|
|
||||||
const factory ActiveLogins({
|
|
||||||
// The list of current logged in accounts
|
|
||||||
required IList<UserLogin> userLogins,
|
|
||||||
// The current selected account indexed by master record key
|
|
||||||
TypedKey? activeUserLogin,
|
|
||||||
}) = _ActiveLogins;
|
|
||||||
|
|
||||||
factory ActiveLogins.empty() =>
|
|
||||||
const ActiveLogins(userLogins: IListConst([]));
|
|
||||||
|
|
||||||
factory ActiveLogins.fromJson(dynamic json) =>
|
|
||||||
_ActiveLogins.fromJson(json as Map<String, dynamic>);
|
|
||||||
}
|
|
@ -1,181 +0,0 @@
|
|||||||
// coverage:ignore-file
|
|
||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
|
||||||
// ignore_for_file: type=lint
|
|
||||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
|
||||||
|
|
||||||
part of 'active_logins.dart';
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// FreezedGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
T _$identity<T>(T value) => value;
|
|
||||||
|
|
||||||
final _privateConstructorUsedError = UnsupportedError(
|
|
||||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
|
||||||
|
|
||||||
ActiveLogins _$ActiveLoginsFromJson(Map<String, dynamic> json) {
|
|
||||||
return _ActiveLogins.fromJson(json);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
mixin _$ActiveLogins {
|
|
||||||
// The list of current logged in accounts
|
|
||||||
IList<UserLogin> get userLogins =>
|
|
||||||
throw _privateConstructorUsedError; // The current selected account indexed by master record key
|
|
||||||
Typed<FixedEncodedString43>? get activeUserLogin =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
|
||||||
@JsonKey(ignore: true)
|
|
||||||
$ActiveLoginsCopyWith<ActiveLogins> get copyWith =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class $ActiveLoginsCopyWith<$Res> {
|
|
||||||
factory $ActiveLoginsCopyWith(
|
|
||||||
ActiveLogins value, $Res Function(ActiveLogins) then) =
|
|
||||||
_$ActiveLoginsCopyWithImpl<$Res, ActiveLogins>;
|
|
||||||
@useResult
|
|
||||||
$Res call(
|
|
||||||
{IList<UserLogin> userLogins,
|
|
||||||
Typed<FixedEncodedString43>? activeUserLogin});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class _$ActiveLoginsCopyWithImpl<$Res, $Val extends ActiveLogins>
|
|
||||||
implements $ActiveLoginsCopyWith<$Res> {
|
|
||||||
_$ActiveLoginsCopyWithImpl(this._value, this._then);
|
|
||||||
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Val _value;
|
|
||||||
// ignore: unused_field
|
|
||||||
final $Res Function($Val) _then;
|
|
||||||
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
@override
|
|
||||||
$Res call({
|
|
||||||
Object? userLogins = null,
|
|
||||||
Object? activeUserLogin = freezed,
|
|
||||||
}) {
|
|
||||||
return _then(_value.copyWith(
|
|
||||||
userLogins: null == userLogins
|
|
||||||
? _value.userLogins
|
|
||||||
: userLogins // ignore: cast_nullable_to_non_nullable
|
|
||||||
as IList<UserLogin>,
|
|
||||||
activeUserLogin: freezed == activeUserLogin
|
|
||||||
? _value.activeUserLogin
|
|
||||||
: activeUserLogin // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Typed<FixedEncodedString43>?,
|
|
||||||
) as $Val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
abstract class _$$ActiveLoginsImplCopyWith<$Res>
|
|
||||||
implements $ActiveLoginsCopyWith<$Res> {
|
|
||||||
factory _$$ActiveLoginsImplCopyWith(
|
|
||||||
_$ActiveLoginsImpl value, $Res Function(_$ActiveLoginsImpl) then) =
|
|
||||||
__$$ActiveLoginsImplCopyWithImpl<$Res>;
|
|
||||||
@override
|
|
||||||
@useResult
|
|
||||||
$Res call(
|
|
||||||
{IList<UserLogin> userLogins,
|
|
||||||
Typed<FixedEncodedString43>? activeUserLogin});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
class __$$ActiveLoginsImplCopyWithImpl<$Res>
|
|
||||||
extends _$ActiveLoginsCopyWithImpl<$Res, _$ActiveLoginsImpl>
|
|
||||||
implements _$$ActiveLoginsImplCopyWith<$Res> {
|
|
||||||
__$$ActiveLoginsImplCopyWithImpl(
|
|
||||||
_$ActiveLoginsImpl _value, $Res Function(_$ActiveLoginsImpl) _then)
|
|
||||||
: super(_value, _then);
|
|
||||||
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
@override
|
|
||||||
$Res call({
|
|
||||||
Object? userLogins = null,
|
|
||||||
Object? activeUserLogin = freezed,
|
|
||||||
}) {
|
|
||||||
return _then(_$ActiveLoginsImpl(
|
|
||||||
userLogins: null == userLogins
|
|
||||||
? _value.userLogins
|
|
||||||
: userLogins // ignore: cast_nullable_to_non_nullable
|
|
||||||
as IList<UserLogin>,
|
|
||||||
activeUserLogin: freezed == activeUserLogin
|
|
||||||
? _value.activeUserLogin
|
|
||||||
: activeUserLogin // ignore: cast_nullable_to_non_nullable
|
|
||||||
as Typed<FixedEncodedString43>?,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @nodoc
|
|
||||||
@JsonSerializable()
|
|
||||||
class _$ActiveLoginsImpl implements _ActiveLogins {
|
|
||||||
const _$ActiveLoginsImpl({required this.userLogins, this.activeUserLogin});
|
|
||||||
|
|
||||||
factory _$ActiveLoginsImpl.fromJson(Map<String, dynamic> json) =>
|
|
||||||
_$$ActiveLoginsImplFromJson(json);
|
|
||||||
|
|
||||||
// The list of current logged in accounts
|
|
||||||
@override
|
|
||||||
final IList<UserLogin> userLogins;
|
|
||||||
// The current selected account indexed by master record key
|
|
||||||
@override
|
|
||||||
final Typed<FixedEncodedString43>? activeUserLogin;
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'ActiveLogins(userLogins: $userLogins, activeUserLogin: $activeUserLogin)';
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool operator ==(Object other) {
|
|
||||||
return identical(this, other) ||
|
|
||||||
(other.runtimeType == runtimeType &&
|
|
||||||
other is _$ActiveLoginsImpl &&
|
|
||||||
const DeepCollectionEquality()
|
|
||||||
.equals(other.userLogins, userLogins) &&
|
|
||||||
(identical(other.activeUserLogin, activeUserLogin) ||
|
|
||||||
other.activeUserLogin == activeUserLogin));
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
|
||||||
@override
|
|
||||||
int get hashCode => Object.hash(runtimeType,
|
|
||||||
const DeepCollectionEquality().hash(userLogins), activeUserLogin);
|
|
||||||
|
|
||||||
@JsonKey(ignore: true)
|
|
||||||
@override
|
|
||||||
@pragma('vm:prefer-inline')
|
|
||||||
_$$ActiveLoginsImplCopyWith<_$ActiveLoginsImpl> get copyWith =>
|
|
||||||
__$$ActiveLoginsImplCopyWithImpl<_$ActiveLoginsImpl>(this, _$identity);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Map<String, dynamic> toJson() {
|
|
||||||
return _$$ActiveLoginsImplToJson(
|
|
||||||
this,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class _ActiveLogins implements ActiveLogins {
|
|
||||||
const factory _ActiveLogins(
|
|
||||||
{required final IList<UserLogin> userLogins,
|
|
||||||
final Typed<FixedEncodedString43>? activeUserLogin}) = _$ActiveLoginsImpl;
|
|
||||||
|
|
||||||
factory _ActiveLogins.fromJson(Map<String, dynamic> json) =
|
|
||||||
_$ActiveLoginsImpl.fromJson;
|
|
||||||
|
|
||||||
@override // The list of current logged in accounts
|
|
||||||
IList<UserLogin> get userLogins;
|
|
||||||
@override // The current selected account indexed by master record key
|
|
||||||
Typed<FixedEncodedString43>? get activeUserLogin;
|
|
||||||
@override
|
|
||||||
@JsonKey(ignore: true)
|
|
||||||
_$$ActiveLoginsImplCopyWith<_$ActiveLoginsImpl> get copyWith =>
|
|
||||||
throw _privateConstructorUsedError;
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
|
||||||
|
|
||||||
part of 'active_logins.dart';
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// JsonSerializableGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
_$ActiveLoginsImpl _$$ActiveLoginsImplFromJson(Map<String, dynamic> json) =>
|
|
||||||
_$ActiveLoginsImpl(
|
|
||||||
userLogins: IList<UserLogin>.fromJson(
|
|
||||||
json['user_logins'], (value) => UserLogin.fromJson(value)),
|
|
||||||
activeUserLogin: json['active_user_login'] == null
|
|
||||||
? null
|
|
||||||
: Typed<FixedEncodedString43>.fromJson(json['active_user_login']),
|
|
||||||
);
|
|
||||||
|
|
||||||
Map<String, dynamic> _$$ActiveLoginsImplToJson(_$ActiveLoginsImpl instance) =>
|
|
||||||
<String, dynamic>{
|
|
||||||
'user_logins': instance.userLogins.toJson(
|
|
||||||
(value) => value.toJson(),
|
|
||||||
),
|
|
||||||
'active_user_login': instance.activeUserLogin?.toJson(),
|
|
||||||
};
|
|
@ -47,9 +47,9 @@ class VeilidChatApp extends StatelessWidget {
|
|||||||
create: (context) =>
|
create: (context) =>
|
||||||
UserLoginsCubit(AccountRepository.instance),
|
UserLoginsCubit(AccountRepository.instance),
|
||||||
),
|
),
|
||||||
BlocProvider<ActiveUserLoginCubit>(
|
BlocProvider<ActiveLocalAccountCubit>(
|
||||||
create: (context) =>
|
create: (context) =>
|
||||||
ActiveUserLoginCubit(AccountRepository.instance),
|
ActiveLocalAccountCubit(AccountRepository.instance),
|
||||||
),
|
),
|
||||||
BlocProvider<PreferencesCubit>(
|
BlocProvider<PreferencesCubit>(
|
||||||
create: (context) =>
|
create: (context) =>
|
||||||
|
@ -2,9 +2,12 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:veilid_support/veilid_support.dart';
|
import 'package:veilid_support/veilid_support.dart';
|
||||||
|
|
||||||
class ActiveChatCubit extends Cubit<TypedKey?> {
|
class ActiveChatCubit extends Cubit<TypedKey?> {
|
||||||
ActiveChatCubit(super.initialState);
|
ActiveChatCubit(super.initialState, this.setHasActiveChat);
|
||||||
|
|
||||||
void setActiveChat(TypedKey? activeChatRemoteConversationRecordKey) {
|
void setActiveChat(TypedKey? activeChatRemoteConversationRecordKey) {
|
||||||
|
setHasActiveChat(activeChatRemoteConversationRecordKey != null);
|
||||||
emit(activeChatRemoteConversationRecordKey);
|
emit(activeChatRemoteConversationRecordKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Function(bool) setHasActiveChat;
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import '../../../chat/chat.dart';
|
|||||||
import '../../../chat_list/chat_list.dart';
|
import '../../../chat_list/chat_list.dart';
|
||||||
import '../../../contact_invitation/contact_invitation.dart';
|
import '../../../contact_invitation/contact_invitation.dart';
|
||||||
import '../../../contacts/contacts.dart';
|
import '../../../contacts/contacts.dart';
|
||||||
|
import '../../../router/router.dart';
|
||||||
import '../../../tools/tools.dart';
|
import '../../../tools/tools.dart';
|
||||||
|
|
||||||
class HomeAccountReadyShell extends StatefulWidget {
|
class HomeAccountReadyShell extends StatefulWidget {
|
||||||
@ -18,58 +19,28 @@ class HomeAccountReadyShell extends StatefulWidget {
|
|||||||
final Widget child;
|
final Widget child;
|
||||||
}
|
}
|
||||||
|
|
||||||
class HomeAccountReadyShellState extends State<HomeAccountReadyShell>
|
class HomeAccountReadyShellState extends State<HomeAccountReadyShell> {
|
||||||
with TickerProviderStateMixin {
|
|
||||||
//
|
//
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
// xxx figure out how to do this switch
|
|
||||||
|
|
||||||
// Widget buildWithLogin(BuildContext context) {
|
|
||||||
// final activeUserLogin = context.watch<ActiveUserLoginCubit>().state;
|
|
||||||
|
|
||||||
// if (activeUserLogin == null) {
|
|
||||||
// // If no logged in user is active, show the loading panel
|
|
||||||
// return const HomeNoActive();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// final accountInfo = AccountRepository.instance
|
|
||||||
// .getAccountInfo(accountMasterRecordKey: activeUserLogin)!;
|
|
||||||
|
|
||||||
// switch (accountInfo.status) {
|
|
||||||
// case AccountInfoStatus.noAccount:
|
|
||||||
// return const HomeAccountMissing();
|
|
||||||
// case AccountInfoStatus.accountInvalid:
|
|
||||||
// return const HomeAccountInvalid();
|
|
||||||
// case AccountInfoStatus.accountLocked:
|
|
||||||
// return const HomeAccountLocked();
|
|
||||||
// case AccountInfoStatus.accountReady:
|
|
||||||
// return Provider<ActiveAccountInfo>.value(
|
|
||||||
// value: accountInfo.activeAccountInfo!,
|
|
||||||
// child: BlocProvider(
|
|
||||||
// create: (context) => AccountRecordCubit(
|
|
||||||
// record: accountInfo.activeAccountInfo!.accountRecord),
|
|
||||||
// child: const HomeAccountReady()));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
// These must be valid already before making this widget,
|
// These must be valid already before making this widget,
|
||||||
// per the ShellRoute above it
|
// per the ShellRoute above it
|
||||||
final activeUserLogin = context.read<ActiveUserLoginCubit>().state!;
|
final activeLocalAccount = context.read<ActiveLocalAccountCubit>().state!;
|
||||||
final accountInfo = AccountRepository.instance
|
final accountInfo =
|
||||||
.getAccountInfo(accountMasterRecordKey: activeUserLogin)!;
|
AccountRepository.instance.getAccountInfo(activeLocalAccount);
|
||||||
final activeAccountInfo = accountInfo.activeAccountInfo!;
|
final activeAccountInfo = accountInfo.activeAccountInfo!;
|
||||||
|
final routerCubit = context.read<RouterCubit>();
|
||||||
|
|
||||||
return Provider<ActiveAccountInfo>.value(
|
return Provider<ActiveAccountInfo>.value(
|
||||||
value: activeAccountInfo,
|
value: activeAccountInfo,
|
||||||
child: BlocProvider(
|
child: BlocProvider(
|
||||||
create: (context) => AccountRecordCubit(
|
create: (context) =>
|
||||||
record: accountInfo.activeAccountInfo!.accountRecord),
|
AccountRecordCubit(record: activeAccountInfo.accountRecord),
|
||||||
child: Builder(builder: (context) {
|
child: Builder(builder: (context) {
|
||||||
final account =
|
final account =
|
||||||
context.watch<AccountRecordCubit>().state.data?.value;
|
context.watch<AccountRecordCubit>().state.data?.value;
|
||||||
@ -92,7 +63,9 @@ class HomeAccountReadyShellState extends State<HomeAccountReadyShell>
|
|||||||
BlocProvider(
|
BlocProvider(
|
||||||
create: (context) => ActiveConversationsCubit(
|
create: (context) => ActiveConversationsCubit(
|
||||||
activeAccountInfo: activeAccountInfo)),
|
activeAccountInfo: activeAccountInfo)),
|
||||||
BlocProvider(create: (context) => ActiveChatCubit(null))
|
BlocProvider(
|
||||||
|
create: (context) =>
|
||||||
|
ActiveChatCubit(null, routerCubit.setHasActiveChat))
|
||||||
], child: widget.child);
|
], child: widget.child);
|
||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
import '../../account_manager/account_manager.dart';
|
||||||
import '../../theme/theme.dart';
|
import '../../theme/theme.dart';
|
||||||
|
import 'home_account_invalid.dart';
|
||||||
|
import 'home_account_locked.dart';
|
||||||
|
import 'home_account_missing.dart';
|
||||||
|
import 'home_no_active.dart';
|
||||||
|
|
||||||
class HomeShell extends StatefulWidget {
|
class HomeShell extends StatefulWidget {
|
||||||
const HomeShell({required this.child, super.key});
|
const HomeShell({required this.child, super.key});
|
||||||
@ -25,6 +32,34 @@ class HomeShellState extends State<HomeShell> {
|
|||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget buildWithLogin(BuildContext context, Widget child) {
|
||||||
|
final activeLocalAccount = context.watch<ActiveLocalAccountCubit>().state;
|
||||||
|
|
||||||
|
if (activeLocalAccount == null) {
|
||||||
|
// If no logged in user is active, show the loading panel
|
||||||
|
return const HomeNoActive();
|
||||||
|
}
|
||||||
|
|
||||||
|
final accountInfo =
|
||||||
|
AccountRepository.instance.getAccountInfo(activeLocalAccount);
|
||||||
|
|
||||||
|
switch (accountInfo.status) {
|
||||||
|
case AccountInfoStatus.noAccount:
|
||||||
|
return const HomeAccountMissing();
|
||||||
|
case AccountInfoStatus.accountInvalid:
|
||||||
|
return const HomeAccountInvalid();
|
||||||
|
case AccountInfoStatus.accountLocked:
|
||||||
|
return const HomeAccountLocked();
|
||||||
|
case AccountInfoStatus.accountReady:
|
||||||
|
return Provider<ActiveAccountInfo>.value(
|
||||||
|
value: accountInfo.activeAccountInfo!,
|
||||||
|
child: BlocProvider(
|
||||||
|
create: (context) => AccountRecordCubit(
|
||||||
|
record: accountInfo.activeAccountInfo!.accountRecord),
|
||||||
|
child: child));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
@ -37,6 +72,6 @@ class HomeShellState extends State<HomeShell> {
|
|||||||
child: DecoratedBox(
|
child: DecoratedBox(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: scale.primaryScale.activeElementBackground),
|
color: scale.primaryScale.activeElementBackground),
|
||||||
child: widget.child)));
|
child: buildWithLogin(context, widget.child))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,6 @@ part 'router_state.dart';
|
|||||||
|
|
||||||
final _rootNavKey = GlobalKey<NavigatorState>(debugLabel: 'rootNavKey');
|
final _rootNavKey = GlobalKey<NavigatorState>(debugLabel: 'rootNavKey');
|
||||||
final _homeNavKey = GlobalKey<NavigatorState>(debugLabel: 'homeNavKey');
|
final _homeNavKey = GlobalKey<NavigatorState>(debugLabel: 'homeNavKey');
|
||||||
final _readyAccountNavKey =
|
|
||||||
GlobalKey<NavigatorState>(debugLabel: 'readyAccountNavKey');
|
|
||||||
|
|
||||||
class RouterCubit extends Cubit<RouterState> {
|
class RouterCubit extends Cubit<RouterState> {
|
||||||
RouterCubit(AccountRepository accountRepository)
|
RouterCubit(AccountRepository accountRepository)
|
||||||
@ -44,12 +42,16 @@ class RouterCubit extends Cubit<RouterState> {
|
|||||||
hasAnyAccount: accountRepository.getLocalAccounts().isNotEmpty));
|
hasAnyAccount: accountRepository.getLocalAccounts().isNotEmpty));
|
||||||
break;
|
break;
|
||||||
case AccountRepositoryChange.userLogins:
|
case AccountRepositoryChange.userLogins:
|
||||||
case AccountRepositoryChange.activeUserLogin:
|
case AccountRepositoryChange.activeLocalAccount:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setHasActiveChat(bool active) {
|
||||||
|
emit(state.copyWith(hasActiveChat: active));
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> close() async {
|
Future<void> close() async {
|
||||||
await _accountRepositorySubscription.cancel();
|
await _accountRepositorySubscription.cancel();
|
||||||
@ -63,37 +65,20 @@ class RouterCubit extends Cubit<RouterState> {
|
|||||||
builder: (context, state) => const IndexPage(),
|
builder: (context, state) => const IndexPage(),
|
||||||
),
|
),
|
||||||
ShellRoute(
|
ShellRoute(
|
||||||
navigatorKey: _homeNavKey,
|
navigatorKey: _homeNavKey,
|
||||||
builder: (context, state, child) => HomeShell(child: child),
|
builder: (context, state, child) =>
|
||||||
routes: [
|
HomeShell(child: HomeAccountReadyShell(child: child)),
|
||||||
GoRoute(
|
routes: [
|
||||||
path: '/home/no_active',
|
GoRoute(
|
||||||
builder: (context, state) => const HomeNoActive(),
|
path: '/home',
|
||||||
),
|
builder: (context, state) => const HomeAccountReadyMain(),
|
||||||
GoRoute(
|
),
|
||||||
path: '/home/account_missing',
|
GoRoute(
|
||||||
builder: (context, state) => const HomeAccountMissing(),
|
path: '/home/chat',
|
||||||
),
|
builder: (context, state) => const HomeAccountReadyChat(),
|
||||||
GoRoute(
|
),
|
||||||
path: '/home/account_locked',
|
],
|
||||||
builder: (context, state) => const HomeAccountLocked(),
|
),
|
||||||
),
|
|
||||||
ShellRoute(
|
|
||||||
navigatorKey: _readyAccountNavKey,
|
|
||||||
builder: (context, state, child) =>
|
|
||||||
HomeAccountReadyShell(child: child),
|
|
||||||
routes: [
|
|
||||||
GoRoute(
|
|
||||||
path: '/home',
|
|
||||||
builder: (context, state) => const HomeAccountReadyMain(),
|
|
||||||
),
|
|
||||||
GoRoute(
|
|
||||||
path: '/home/chat',
|
|
||||||
builder: (context, state) => const HomeAccountReadyChat(),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/new_account',
|
path: '/new_account',
|
||||||
builder: (context, state) => const NewAccountPage(),
|
builder: (context, state) => const NewAccountPage(),
|
||||||
@ -127,9 +112,6 @@ class RouterCubit extends Cubit<RouterState> {
|
|||||||
if (!state.hasAnyAccount) {
|
if (!state.hasAnyAccount) {
|
||||||
return '/new_account';
|
return '/new_account';
|
||||||
}
|
}
|
||||||
if (!state.hasActiveChat) { xxx stop using hasActiveChat here... we need a pager for the accounts and a way to get the current account state maybe a 'activeAccountCubit' or something, we may have this alraeady but it needs to work even if logged out.``
|
|
||||||
return '/home/no_active';
|
|
||||||
}
|
|
||||||
if (responsiveVisibility(
|
if (responsiveVisibility(
|
||||||
context: context,
|
context: context,
|
||||||
tablet: false,
|
tablet: false,
|
||||||
@ -144,9 +126,6 @@ class RouterCubit extends Cubit<RouterState> {
|
|||||||
if (!state.hasAnyAccount) {
|
if (!state.hasAnyAccount) {
|
||||||
return '/new_account';
|
return '/new_account';
|
||||||
}
|
}
|
||||||
if (!state.hasActiveChat) {
|
|
||||||
return '/home/no_active';
|
|
||||||
}
|
|
||||||
if (responsiveVisibility(
|
if (responsiveVisibility(
|
||||||
context: context,
|
context: context,
|
||||||
tablet: false,
|
tablet: false,
|
||||||
@ -159,21 +138,6 @@ class RouterCubit extends Cubit<RouterState> {
|
|||||||
return '/home';
|
return '/home';
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
case '/home/no_active':
|
|
||||||
if (state.hasActiveChat) {
|
|
||||||
return '/home';
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
case '/home/account_missing':
|
|
||||||
if (!state.hasActiveChat) {
|
|
||||||
return '/home/no_active';
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
case '/home/account_locked':
|
|
||||||
if (!state.hasActiveChat) {
|
|
||||||
return '/home/no_active';
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
case '/settings':
|
case '/settings':
|
||||||
return null;
|
return null;
|
||||||
case '/developer':
|
case '/developer':
|
||||||
|
Loading…
x
Reference in New Issue
Block a user