Browse Source

Merge pull request #1033 from nextcloud/doc/neon_blocs

docs(neon): document neon blocs
pull/1029/head
Nikolas Rimikis 1 year ago committed by GitHub
parent
commit
2e5cf66336
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 25
      packages/neon/neon/lib/src/bloc/bloc.dart
  2. 7
      packages/neon/neon/lib/src/blocs/accounts.dart
  3. 15
      packages/neon/neon/lib/src/blocs/apps.dart
  4. 1
      packages/neon/neon/lib/src/blocs/capabilities.dart

25
packages/neon/neon/lib/src/bloc/bloc.dart

@ -4,12 +4,23 @@ import 'package:flutter/foundation.dart';
import 'package:neon/src/models/disposable.dart';
import 'package:neon/src/utils/request_manager.dart';
/// A Bloc for implementing the Business Logic Component pattern.
///
/// This design pattern helps to separate presentation from business logic.
/// Following the BLoC pattern facilitates testability and reusability.
///
/// If you are new to Flutter you might want to read:
/// https://www.didierboelens.com/blog/en/reactive-programming-streams-bloc
abstract class Bloc implements Disposable {
@override
@mustCallSuper
void dispose();
}
/// A bloc implementing basic data fetching.
///
/// See:
/// * [Bloc]: for a generic bloc.
abstract class InteractiveBloc extends Bloc {
@override
void dispose() {
@ -17,14 +28,28 @@ abstract class InteractiveBloc extends Bloc {
}
final _errorsStreamController = StreamController<Object>();
/// A stream of error events.
late Stream<Object> errors = _errorsStreamController.stream.asBroadcastStream();
/// Refreshes the state of the bloc.
///
/// Commonly involves re-fetching data from the server.
FutureOr<void> refresh();
/// Adds an error to the [errors] state.
@protected
void addError(final Object error) {
_errorsStreamController.add(error);
}
/// Wraps the action [call].
///
/// If [disableTimeout] is `true` [RequestManager] will apply the default
/// timeout. On success the state will be refreshed through the [refresh]
/// callback falling back to [this.refresh] if not supplied. Any errors will
/// be forwarded to [addError].
@protected
// ignore: avoid_void_async
void wrapAction(
final AsyncCallback call, {

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

@ -21,6 +21,7 @@ import 'package:rxdart/rxdart.dart';
const _keyAccounts = 'accounts';
/// Events for the [AccountsBloc].
@internal
abstract interface class AccountsBlocEvents {
/// Logs in the given [account].
@ -45,6 +46,7 @@ abstract interface class AccountsBlocEvents {
void setActiveAccount(final Account account);
}
/// States for the [AccountsBloc].
@internal
abstract interface class AccountsBlocStates {
/// All registered accounts.
@ -59,7 +61,12 @@ abstract interface class AccountsBlocStates {
BehaviorSubject<Account?> get activeAccount;
}
/// The Bloc responsible for managing the [Account]s
class AccountsBloc extends Bloc implements AccountsBlocEvents, AccountsBlocStates {
/// Creates a new account bloc.
///
/// The last state will be loaded from storage and all necessary listeners
/// will be set up.
AccountsBloc(
this._globalOptions,
this._allAppImplementations,

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

@ -16,6 +16,7 @@ import 'package:nextcloud/nextcloud.dart';
import 'package:provider/provider.dart';
import 'package:rxdart/rxdart.dart';
/// Events for the [AppsBloc].
@internal
abstract interface class AppsBlocEvents {
/// Sets the active app using the [appID].
@ -25,21 +26,31 @@ abstract interface class AppsBlocEvents {
void setActiveApp(final String appID, {final bool skipAlreadySet = false});
}
/// States for the [AppsBloc].
@internal
abstract interface class AppsBlocStates {
/// A collection of clients used in the app drawer.
///
/// It does not contain clients for that are specially handled like for the notifications.
BehaviorSubject<Result<Iterable<AppImplementation>>> get appImplementations;
/// The interface of the notifications app.
BehaviorSubject<Result<NotificationsAppInterface?>> get notificationsAppImplementation;
/// The currently active app.
BehaviorSubject<AppImplementation> get activeApp;
/// A subject emitting an event when the notifications page should be opened.
BehaviorSubject<void> get openNotifications;
/// A collection of unsupported apps and their minimum required version.
BehaviorSubject<Map<String, String?>> get appVersions;
}
/// The Bloc responsible for managing the [AppImplementation]s.
@internal
class AppsBloc extends InteractiveBloc implements AppsBlocEvents, AppsBlocStates {
/// Creates a new apps bloc.
AppsBloc(
this._capabilitiesBloc,
this._accountsBloc,
@ -229,9 +240,13 @@ class AppsBloc extends InteractiveBloc implements AppsBlocEvents, AppsBlocStates
}
}
/// Returns the active [Bloc] for the given [appImplementation].
///
/// If no bloc exists yet a new one will be instantiated and cached in [AppImplementation.blocsCache].
T getAppBloc<T extends Bloc>(final AppImplementation<T, dynamic> appImplementation) =>
appImplementation.getBloc(_account);
/// Returns the active [Bloc] for every registered [AppImplementation] wrapped in a Provider.
List<Provider<Bloc>> get appBlocProviders =>
_allAppImplementations.map((final appImplementation) => appImplementation.blocProvider).toList();
}

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

@ -18,6 +18,7 @@ abstract interface class CapabilitiesBlocStates {
@internal
class CapabilitiesBloc extends InteractiveBloc implements CapabilitiesBlocEvents, CapabilitiesBlocStates {
/// Creates a new capabilities bloc.
CapabilitiesBloc(
this._account,
) {

Loading…
Cancel
Save