Browse Source

neon: Display storage quota for accounts

pull/54/head
jld3103 2 years ago
parent
commit
ab6109760e
No known key found for this signature in database
GPG Key ID: 9062417B9E8EB7B3
  1. 15
      packages/neon/lib/l10n/en.arb
  2. 12
      packages/neon/lib/l10n/localizations.dart
  3. 8
      packages/neon/lib/l10n/localizations_en.dart
  4. 6
      packages/neon/lib/src/blocs/user_details.dart
  5. 7
      packages/neon/lib/src/blocs/user_details.rxb.g.dart
  6. 1
      packages/neon/lib/src/neon.dart
  7. 45
      packages/neon/lib/src/pages/settings/account_specific_settings.dart

15
packages/neon/lib/l10n/en.arb

@ -104,6 +104,21 @@
} }
} }
}, },
"accountOptionsCategoryStorageInfo": "Storage info",
"accountOptionsQuotaUsedOf": "{used} used of {total} ({relative}%)",
"@accountOptionsQuotaUsedOf": {
"placeholders": {
"used": {
"type": "String"
},
"total": {
"type": "String"
},
"relative": {
"type": "String"
}
}
},
"accountOptionsInitialApp": "App to show initially", "accountOptionsInitialApp": "App to show initially",
"accountOptionsAutomatic": "Automatic", "accountOptionsAutomatic": "Automatic",
"licenses": "Licenses", "licenses": "Licenses",

12
packages/neon/lib/l10n/localizations.dart

@ -503,6 +503,18 @@ abstract class AppLocalizations {
/// **'Are you sure you want to remove the account {id}?'** /// **'Are you sure you want to remove the account {id}?'**
String accountOptionsRemoveConfirm(String id); String accountOptionsRemoveConfirm(String id);
/// No description provided for @accountOptionsCategoryStorageInfo.
///
/// In en, this message translates to:
/// **'Storage info'**
String get accountOptionsCategoryStorageInfo;
/// No description provided for @accountOptionsQuotaUsedOf.
///
/// In en, this message translates to:
/// **'{used} used of {total} ({relative}%)'**
String accountOptionsQuotaUsedOf(String used, String total, String relative);
/// No description provided for @accountOptionsInitialApp. /// No description provided for @accountOptionsInitialApp.
/// ///
/// In en, this message translates to: /// In en, this message translates to:

8
packages/neon/lib/l10n/localizations_en.dart

@ -226,6 +226,14 @@ class AppLocalizationsEn extends AppLocalizations {
return 'Are you sure you want to remove the account $id?'; return 'Are you sure you want to remove the account $id?';
} }
@override
String get accountOptionsCategoryStorageInfo => 'Storage info';
@override
String accountOptionsQuotaUsedOf(String used, String total, String relative) {
return '$used used of $total ($relative%)';
}
@override @override
String get accountOptionsInitialApp => 'App to show initially'; String get accountOptionsInitialApp => 'App to show initially';

6
packages/neon/lib/src/blocs/user_details.dart

@ -6,7 +6,9 @@ import 'package:rxdart/rxdart.dart';
part 'user_details.rxb.g.dart'; part 'user_details.rxb.g.dart';
abstract class UserDetailsBlocEvents {} abstract class UserDetailsBlocEvents {
void refresh();
}
abstract class UserDetailsBlocStates { abstract class UserDetailsBlocStates {
BehaviorSubject<Result<ProvisioningApiUserDetails>> get userDetails; BehaviorSubject<Result<ProvisioningApiUserDetails>> get userDetails;
@ -18,6 +20,8 @@ class UserDetailsBloc extends $UserDetailsBloc {
this._requestManager, this._requestManager,
this._client, this._client,
) { ) {
_$refreshEvent.listen((final _) => _loadUserDetails());
_loadUserDetails(); _loadUserDetails();
} }

7
packages/neon/lib/src/blocs/user_details.rxb.g.dart

@ -19,9 +19,15 @@ abstract class $UserDetailsBloc extends RxBlocBase
implements UserDetailsBlocEvents, UserDetailsBlocStates, UserDetailsBlocType { implements UserDetailsBlocEvents, UserDetailsBlocStates, UserDetailsBlocType {
final _compositeSubscription = CompositeSubscription(); final _compositeSubscription = CompositeSubscription();
/// Тhe [Subject] where events sink to by calling [refresh]
final _$refreshEvent = PublishSubject<void>();
/// The state of [userDetails] implemented in [_mapToUserDetailsState] /// The state of [userDetails] implemented in [_mapToUserDetailsState]
late final BehaviorSubject<Result<ProvisioningApiUserDetails>> _userDetailsState = _mapToUserDetailsState(); late final BehaviorSubject<Result<ProvisioningApiUserDetails>> _userDetailsState = _mapToUserDetailsState();
@override
void refresh() => _$refreshEvent.add(null);
@override @override
BehaviorSubject<Result<ProvisioningApiUserDetails>> get userDetails => _userDetailsState; BehaviorSubject<Result<ProvisioningApiUserDetails>> get userDetails => _userDetailsState;
@ -35,6 +41,7 @@ abstract class $UserDetailsBloc extends RxBlocBase
@override @override
void dispose() { void dispose() {
_$refreshEvent.close();
_compositeSubscription.dispose(); _compositeSubscription.dispose();
super.dispose(); super.dispose();
} }

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

@ -9,6 +9,7 @@ import 'dart:typed_data';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:crypto/crypto.dart'; import 'package:crypto/crypto.dart';
import 'package:file_picker/file_picker.dart'; import 'package:file_picker/file_picker.dart';
import 'package:filesize/filesize.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_file_dialog/flutter_file_dialog.dart'; import 'package:flutter_file_dialog/flutter_file_dialog.dart';

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

@ -11,6 +11,7 @@ class AccountSpecificSettingsPage extends StatelessWidget {
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 _name = account.client.humanReadableID; late final _name = account.client.humanReadableID;
@override @override
@ -44,8 +45,49 @@ class AccountSpecificSettingsPage extends StatelessWidget {
), ),
], ],
), ),
body: SettingsList( body: StandardRxResultBuilder<UserDetailsBloc, ProvisioningApiUserDetails>(
bloc: _userDetailsBloc,
state: (final bloc) => bloc.userDetails,
builder: (final context, final userDetailsData, final userDetailsError, final userDetailsLoading, final _) =>
SettingsList(
categories: [ categories: [
SettingsCategory(
title: Text(AppLocalizations.of(context).accountOptionsCategoryStorageInfo),
tiles: [
CustomSettingsTile(
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (userDetailsData != null) ...[
LinearProgressIndicator(
value: userDetailsData.quota!.relative! / 100,
backgroundColor: Theme.of(context).colorScheme.primary.withOpacity(0.3),
),
const SizedBox(
height: 10,
),
Text(
AppLocalizations.of(context).accountOptionsQuotaUsedOf(
filesize(userDetailsData.quota!.used!, 1),
filesize(userDetailsData.quota!.total!, 1),
userDetailsData.quota!.relative!.toString(),
),
),
],
ExceptionWidget(
userDetailsError,
onRetry: () {
_userDetailsBloc.refresh();
},
),
CustomLinearProgressIndicator(
visible: userDetailsLoading,
),
],
),
),
],
),
SettingsCategory( SettingsCategory(
title: Text(AppLocalizations.of(context).optionsCategoryGeneral), title: Text(AppLocalizations.of(context).optionsCategoryGeneral),
tiles: [ tiles: [
@ -56,5 +98,6 @@ class AccountSpecificSettingsPage extends StatelessWidget {
), ),
], ],
), ),
),
); );
} }

Loading…
Cancel
Save