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/models/disposable.dart';
import 'package:neon/src/utils/request_manager.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 { abstract class Bloc implements Disposable {
@override @override
@mustCallSuper @mustCallSuper
void dispose(); void dispose();
} }
/// A bloc implementing basic data fetching.
///
/// See:
/// * [Bloc]: for a generic bloc.
abstract class InteractiveBloc extends Bloc { abstract class InteractiveBloc extends Bloc {
@override @override
void dispose() { void dispose() {
@ -17,14 +28,28 @@ abstract class InteractiveBloc extends Bloc {
} }
final _errorsStreamController = StreamController<Object>(); final _errorsStreamController = StreamController<Object>();
/// A stream of error events.
late Stream<Object> errors = _errorsStreamController.stream.asBroadcastStream(); late Stream<Object> errors = _errorsStreamController.stream.asBroadcastStream();
/// Refreshes the state of the bloc.
///
/// Commonly involves re-fetching data from the server.
FutureOr<void> refresh(); FutureOr<void> refresh();
/// Adds an error to the [errors] state.
@protected
void addError(final Object error) { void addError(final Object error) {
_errorsStreamController.add(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 // ignore: avoid_void_async
void wrapAction( void wrapAction(
final AsyncCallback call, { final AsyncCallback call, {

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

@ -21,6 +21,7 @@ import 'package:rxdart/rxdart.dart';
const _keyAccounts = 'accounts'; const _keyAccounts = 'accounts';
/// Events for the [AccountsBloc].
@internal @internal
abstract interface class AccountsBlocEvents { abstract interface class AccountsBlocEvents {
/// Logs in the given [account]. /// Logs in the given [account].
@ -45,6 +46,7 @@ abstract interface class AccountsBlocEvents {
void setActiveAccount(final Account account); void setActiveAccount(final Account account);
} }
/// States for the [AccountsBloc].
@internal @internal
abstract interface class AccountsBlocStates { abstract interface class AccountsBlocStates {
/// All registered accounts. /// All registered accounts.
@ -59,7 +61,12 @@ abstract interface class AccountsBlocStates {
BehaviorSubject<Account?> get activeAccount; BehaviorSubject<Account?> get activeAccount;
} }
/// The Bloc responsible for managing the [Account]s
class AccountsBloc extends Bloc implements AccountsBlocEvents, AccountsBlocStates { 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( AccountsBloc(
this._globalOptions, this._globalOptions,
this._allAppImplementations, 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:provider/provider.dart';
import 'package:rxdart/rxdart.dart'; import 'package:rxdart/rxdart.dart';
/// Events for the [AppsBloc].
@internal @internal
abstract interface class AppsBlocEvents { abstract interface class AppsBlocEvents {
/// Sets the active app using the [appID]. /// Sets the active app using the [appID].
@ -25,21 +26,31 @@ abstract interface class AppsBlocEvents {
void setActiveApp(final String appID, {final bool skipAlreadySet = false}); void setActiveApp(final String appID, {final bool skipAlreadySet = false});
} }
/// States for the [AppsBloc].
@internal @internal
abstract interface class AppsBlocStates { 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; BehaviorSubject<Result<Iterable<AppImplementation>>> get appImplementations;
/// The interface of the notifications app.
BehaviorSubject<Result<NotificationsAppInterface?>> get notificationsAppImplementation; BehaviorSubject<Result<NotificationsAppInterface?>> get notificationsAppImplementation;
/// The currently active app.
BehaviorSubject<AppImplementation> get activeApp; BehaviorSubject<AppImplementation> get activeApp;
/// A subject emitting an event when the notifications page should be opened.
BehaviorSubject<void> get openNotifications; BehaviorSubject<void> get openNotifications;
/// A collection of unsupported apps and their minimum required version.
BehaviorSubject<Map<String, String?>> get appVersions; BehaviorSubject<Map<String, String?>> get appVersions;
} }
/// The Bloc responsible for managing the [AppImplementation]s.
@internal @internal
class AppsBloc extends InteractiveBloc implements AppsBlocEvents, AppsBlocStates { class AppsBloc extends InteractiveBloc implements AppsBlocEvents, AppsBlocStates {
/// Creates a new apps bloc.
AppsBloc( AppsBloc(
this._capabilitiesBloc, this._capabilitiesBloc,
this._accountsBloc, 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) => T getAppBloc<T extends Bloc>(final AppImplementation<T, dynamic> appImplementation) =>
appImplementation.getBloc(_account); appImplementation.getBloc(_account);
/// Returns the active [Bloc] for every registered [AppImplementation] wrapped in a Provider.
List<Provider<Bloc>> get appBlocProviders => List<Provider<Bloc>> get appBlocProviders =>
_allAppImplementations.map((final appImplementation) => appImplementation.blocProvider).toList(); _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 @internal
class CapabilitiesBloc extends InteractiveBloc implements CapabilitiesBlocEvents, CapabilitiesBlocStates { class CapabilitiesBloc extends InteractiveBloc implements CapabilitiesBlocEvents, CapabilitiesBlocStates {
/// Creates a new capabilities bloc.
CapabilitiesBloc( CapabilitiesBloc(
this._account, this._account,
) { ) {

Loading…
Cancel
Save