Browse Source

Merge pull request #67 from jld3103/fix/account-settings-apps-loading

Fix account settings not loading apps
pull/68/head
jld3103 2 years ago committed by GitHub
parent
commit
77c40376f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      packages/neon/integration_test/screenshot_test.dart
  2. 1
      packages/neon/lib/main.dart
  3. 28
      packages/neon/lib/src/blocs/accounts.dart
  4. 2
      packages/neon/lib/src/blocs/apps.dart
  5. 49
      packages/neon/lib/src/models/account.dart
  6. 1
      packages/neon/lib/src/neon.dart
  7. 7
      packages/neon/lib/src/pages/home/home.dart
  8. 2
      packages/neon/lib/src/pages/settings/account_specific_settings.dart
  9. 4
      packages/neon/lib/src/pages/settings/settings.dart
  10. 48
      packages/neon/lib/src/utils/account_options.dart

1
packages/neon/integration_test/screenshot_test.dart

@ -119,6 +119,7 @@ Future pumpAppPage(
sharedPreferences, sharedPreferences,
globalOptions, globalOptions,
packageInfo, packageInfo,
allAppImplementations,
); );
if (account != null) { if (account != null) {
accountsBloc.addAccount(account..setupClient(packageInfo)); accountsBloc.addAccount(account..setupClient(packageInfo));

1
packages/neon/lib/main.dart

@ -47,6 +47,7 @@ Future main() async {
sharedPreferences, sharedPreferences,
globalOptions, globalOptions,
packageInfo, packageInfo,
allAppImplementations,
); );
final pushNotificationsBloc = PushNotificationsBloc( final pushNotificationsBloc = PushNotificationsBloc(
accountsBloc, accountsBloc,

28
packages/neon/lib/src/blocs/accounts.dart

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'package:neon/src/blocs/apps.dart';
import 'package:neon/src/blocs/user_details.dart'; import 'package:neon/src/blocs/user_details.dart';
import 'package:neon/src/blocs/user_status.dart'; import 'package:neon/src/blocs/user_status.dart';
import 'package:neon/src/models/account.dart'; import 'package:neon/src/models/account.dart';
@ -32,6 +33,7 @@ class AccountsBloc extends $AccountsBloc {
this._sharedPreferences, this._sharedPreferences,
this._globalOptions, this._globalOptions,
this._packageInfo, this._packageInfo,
this._allAppImplementations,
) { ) {
_accountsSubject.listen((final accounts) async { _accountsSubject.listen((final accounts) async {
_globalOptions.updateAccounts(accounts); _globalOptions.updateAccounts(accounts);
@ -118,30 +120,34 @@ class AccountsBloc extends $AccountsBloc {
} }
} }
AccountSpecificOptions? getOptions([Account? account]) { AccountSpecificOptions getOptions(final Account account) => _accountsOptions[account.id] ??= AccountSpecificOptions(
account ??= _activeAccountSubject.valueOrNull; Storage('accounts-${account.id}', _sharedPreferences),
if (account != null) { getAppsBloc(account),
final accountID = account.id; );
if (_accountsOptions[accountID] != null) {
return _accountsOptions[accountID];
}
return _accountsOptions[accountID] = AppsBloc getAppsBloc(final Account account) {
AccountSpecificOptions(Storage('accounts-${account.id}', _sharedPreferences)); if (_accountsAppsBlocs[account.id] != null) {
return _accountsAppsBlocs[account.id]!;
} }
return AppsBloc(
return null; _requestManager,
this,
account,
_allAppImplementations,
);
} }
final RequestManager _requestManager; final RequestManager _requestManager;
final Storage _storage; final Storage _storage;
final SharedPreferences _sharedPreferences; final SharedPreferences _sharedPreferences;
final GlobalOptions _globalOptions; final GlobalOptions _globalOptions;
final List<AppImplementation> _allAppImplementations;
final PackageInfo _packageInfo; final PackageInfo _packageInfo;
final _keyAccounts = 'accounts'; final _keyAccounts = 'accounts';
final _keyLastUsedAccount = 'last-used-account'; final _keyLastUsedAccount = 'last-used-account';
final _accountsOptions = <String, AccountSpecificOptions>{}; final _accountsOptions = <String, AccountSpecificOptions>{};
final _accountsAppsBlocs = <String, AppsBloc>{};
late final _activeAccountSubject = BehaviorSubject<Account?>.seeded(null); late final _activeAccountSubject = BehaviorSubject<Account?>.seeded(null);
late final _accountsSubject = BehaviorSubject<List<Account>>.seeded([]); late final _accountsSubject = BehaviorSubject<List<Account>>.seeded([]);
String? pushNotificationApp; String? pushNotificationApp;

2
packages/neon/lib/src/blocs/apps.dart

@ -66,7 +66,7 @@ class AppsBloc extends $AppsBloc {
setActiveApp(_accountsBloc.pushNotificationApp); setActiveApp(_accountsBloc.pushNotificationApp);
_accountsBloc.pushNotificationApp = null; _accountsBloc.pushNotificationApp = null;
} else { } else {
final options = _accountsBloc.getOptions(_account)!..updateApps(appImplementations); final options = _accountsBloc.getOptions(_account);
unawaited( unawaited(
options.initialApp.stream.first.then((var initialApp) { options.initialApp.stream.first.then((var initialApp) {
if (initialApp == null) { if (initialApp == null) {

49
packages/neon/lib/src/models/account.dart

@ -1,14 +1,9 @@
import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'package:crypto/crypto.dart'; import 'package:crypto/crypto.dart';
import 'package:json_annotation/json_annotation.dart'; import 'package:json_annotation/json_annotation.dart';
import 'package:neon/l10n/localizations.dart';
import 'package:neon/src/neon.dart';
import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/nextcloud.dart';
import 'package:package_info_plus/package_info_plus.dart'; import 'package:package_info_plus/package_info_plus.dart';
import 'package:rxdart/rxdart.dart';
import 'package:settings/settings.dart';
part 'account.g.dart'; part 'account.g.dart';
@ -86,47 +81,3 @@ extension NextcloudClientHelpers on NextcloudClient {
return '${username!}@${uri.port != 443 ? '${uri.host}:${uri.port}' : uri.host}'; return '${username!}@${uri.port != 443 ? '${uri.host}:${uri.port}' : uri.host}';
} }
} }
class AccountSpecificOptions {
AccountSpecificOptions(this._storage);
final Storage _storage;
final _appIDsSubject = BehaviorSubject<Map<String?, LabelBuilder>>();
late final List<Option> options = [
initialApp,
];
void updateApps(final List<AppImplementation> apps) {
if (apps.isEmpty) {
return;
}
_appIDsSubject.add({
null: (final context) => AppLocalizations.of(context).accountOptionsAutomatic,
for (final app in apps) ...{
app.id: app.name,
},
});
}
Future reset() async {
for (final option in options) {
await option.reset();
}
}
void dispose() {
unawaited(_appIDsSubject.close());
for (final option in options) {
option.dispose();
}
}
late final initialApp = SelectOption<String?>(
storage: _storage,
key: 'initial-app',
label: (final context) => AppLocalizations.of(context).accountOptionsInitialApp,
defaultValue: BehaviorSubject.seeded(null),
values: _appIDsSubject,
);
}

1
packages/neon/lib/src/neon.dart

@ -64,6 +64,7 @@ part 'platform/abstract.dart';
part 'platform/android.dart'; part 'platform/android.dart';
part 'platform/linux.dart'; part 'platform/linux.dart';
part 'platform/platform.dart'; part 'platform/platform.dart';
part 'utils/account_options.dart';
part 'utils/app_implementation.dart'; part 'utils/app_implementation.dart';
part 'utils/confirmation_dialog.dart'; part 'utils/confirmation_dialog.dart';
part 'utils/custom_timeago.dart'; part 'utils/custom_timeago.dart';

7
packages/neon/lib/src/pages/home/home.dart

@ -35,6 +35,7 @@ class _HomePageState extends State<HomePage> with tray.TrayListener, WindowListe
_platform = Provider.of<NeonPlatform>(context, listen: false); _platform = Provider.of<NeonPlatform>(context, listen: false);
_globalOptions = Provider.of<GlobalOptions>(context, listen: false); _globalOptions = Provider.of<GlobalOptions>(context, listen: false);
final accountsBloc = RxBlocProvider.of<AccountsBloc>(context); final accountsBloc = RxBlocProvider.of<AccountsBloc>(context);
_appsBloc = accountsBloc.getAppsBloc(widget.account);
if (_platform.canUseSystemTray) { if (_platform.canUseSystemTray) {
tray.trayManager.addListener(this); tray.trayManager.addListener(this);
@ -94,12 +95,6 @@ class _HomePageState extends State<HomePage> with tray.TrayListener, WindowListe
} }
} }
}); });
_appsBloc = AppsBloc(
_requestManager,
accountsBloc,
widget.account,
Provider.of<List<AppImplementation>>(context, listen: false),
);
WidgetsBinding.instance.addPostFrameCallback((final _) async { WidgetsBinding.instance.addPostFrameCallback((final _) async {
final appImplementations = Provider.of<List<AppImplementation>>(context, listen: false); final appImplementations = Provider.of<List<AppImplementation>>(context, listen: false);

2
packages/neon/lib/src/pages/settings/account_specific_settings.dart

@ -10,7 +10,7 @@ class AccountSpecificSettingsPage extends StatelessWidget {
final AccountsBloc bloc; final AccountsBloc bloc;
final Account account; final Account account;
late final _options = bloc.getOptions(account)!; late final _options = bloc.getOptions(account);
late final _userDetailsBloc = bloc.getUserDetailsBloc(account); late final _userDetailsBloc = bloc.getUserDetailsBloc(account);
late final _name = account.client.humanReadableID; late final _name = account.client.humanReadableID;

4
packages/neon/lib/src/pages/settings/settings.dart

@ -30,7 +30,7 @@ class _SettingsPageState extends State<SettingsPage> {
} }
for (final account in accountsBloc.accounts.value) { for (final account in accountsBloc.accounts.value) {
await accountsBloc.getOptions(account)!.reset(); await accountsBloc.getOptions(account).reset();
} }
} }
}, },
@ -52,7 +52,7 @@ class _SettingsPageState extends State<SettingsPage> {
accountSpecificOptions: { accountSpecificOptions: {
if (accountsSnapshot.hasData) ...{ if (accountsSnapshot.hasData) ...{
for (final account in accountsSnapshot.data!) ...{ for (final account in accountsSnapshot.data!) ...{
account: accountsBloc.getOptions(account)!.options, account: accountsBloc.getOptions(account).options,
}, },
}, },
}, },

48
packages/neon/lib/src/utils/account_options.dart

@ -0,0 +1,48 @@
part of '../neon.dart';
class AccountSpecificOptions {
AccountSpecificOptions(
this._storage,
this._appsBloc,
) {
_appsBloc.appImplementations.listen((final result) {
if (result.data != null) {
_appIDsSubject.add({
null: (final context) => AppLocalizations.of(context).accountOptionsAutomatic,
for (final app in result.data!) ...{
app.id: app.name,
},
});
}
});
}
final Storage _storage;
final AppsBloc _appsBloc;
final _appIDsSubject = BehaviorSubject<Map<String?, LabelBuilder>>();
late final List<Option> options = [
initialApp,
];
Future reset() async {
for (final option in options) {
await option.reset();
}
}
void dispose() {
unawaited(_appIDsSubject.close());
for (final option in options) {
option.dispose();
}
}
late final initialApp = SelectOption<String?>(
storage: _storage,
key: 'initial-app',
label: (final context) => AppLocalizations.of(context).accountOptionsInitialApp,
defaultValue: BehaviorSubject.seeded(null),
values: _appIDsSubject,
);
}
Loading…
Cancel
Save