Skip to content

Commit

Permalink
refactor(neon_framework): Make AppImplementations a BuiltSet
Browse files Browse the repository at this point in the history
Signed-off-by: provokateurin <kate@provokateurin.de>
  • Loading branch information
provokateurin committed Feb 14, 2024
1 parent 19e5c95 commit a70b125
Show file tree
Hide file tree
Showing 15 changed files with 40 additions and 29 deletions.
5 changes: 3 additions & 2 deletions packages/app/lib/apps.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:built_collection/built_collection.dart';
import 'package:neon_dashboard/neon_dashboard.dart';
import 'package:neon_files/neon_files.dart';
import 'package:neon_framework/models.dart';
Expand All @@ -6,10 +7,10 @@ import 'package:neon_notes/neon_notes.dart';
import 'package:neon_notifications/neon_notifications.dart';

/// The collection of clients enabled for the Neon app.
final Set<AppImplementation> appImplementations = {
final BuiltSet<AppImplementation> appImplementations = BuiltSet({
DashboardApp(),
FilesApp(),
NewsApp(),
NotesApp(),
NotificationsApp(),
};
});
2 changes: 1 addition & 1 deletion packages/app/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ packages:
source: hosted
version: "1.1.1"
built_collection:
dependency: transitive
dependency: "direct main"
description:
name: built_collection
sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100"
Expand Down
1 change: 1 addition & 0 deletions packages/app/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ environment:
flutter: '>=3.16.0'

dependencies:
built_collection: ^5.0.0
flutter:
sdk: flutter
neon_dashboard:
Expand Down
2 changes: 1 addition & 1 deletion packages/neon/neon_notifications/lib/src/pages/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class _NotificationsMainPageState extends State<NotificationsMainPage> {
BuildContext context,
notifications.Notification notification,
) {
final app = NeonProvider.of<Iterable<AppImplementation>>(context).tryFind(notification.app);
final app = NeonProvider.of<BuiltSet<AppImplementation>>(context).tryFind(notification.app);

return ListTile(
title: Text(notification.subject),
Expand Down
5 changes: 3 additions & 2 deletions packages/neon_framework/lib/neon.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:async';

import 'package:built_collection/built_collection.dart';
import 'package:flutter/material.dart';
import 'package:flutter_native_splash/flutter_native_splash.dart';
import 'package:neon_framework/src/app.dart';
Expand All @@ -23,7 +24,7 @@ import 'package:provider/provider.dart';
///
/// Optionally provide a [theme] to set the default style.
Future<void> runNeon({
required Set<AppImplementation> appImplementations,
required BuiltSet<AppImplementation> appImplementations,
required NeonTheme theme,
@visibleForTesting WidgetsBinding? bindingOverride,
@visibleForTesting Account? account,
Expand Down Expand Up @@ -72,7 +73,7 @@ Future<void> runNeon({
NeonProvider<AccountsBloc>.value(value: accountsBloc),
NeonProvider<FirstLaunchBloc>.value(value: firstLaunchBloc),
NeonProvider<NextPushBloc>.value(value: nextPushBloc),
Provider<Iterable<AppImplementation>>(
Provider<BuiltSet<AppImplementation>>(
create: (_) => appImplementations,
dispose: (_, appImplementations) => appImplementations.disposeAll(),
),
Expand Down
9 changes: 5 additions & 4 deletions packages/neon_framework/lib/src/app.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:convert';

import 'package:built_collection/built_collection.dart';
import 'package:collection/collection.dart';
import 'package:dynamic_color/dynamic_color.dart';
import 'package:flutter/material.dart';
Expand Down Expand Up @@ -55,7 +56,7 @@ class NeonApp extends StatefulWidget {
class _NeonAppState extends State<NeonApp> with WidgetsBindingObserver, WindowListener {
final _appRegex = RegExp(r'^app_([a-z]+)$', multiLine: true);
final _navigatorKey = GlobalKey<NavigatorState>();
late final Iterable<AppImplementation> _appImplementations;
late final BuiltSet<AppImplementation> _appImplementations;
late final GlobalOptions _globalOptions;
late final AccountsBloc _accountsBloc;
late final _routerDelegate = buildAppRouter(
Expand All @@ -67,7 +68,7 @@ class _NeonAppState extends State<NeonApp> with WidgetsBindingObserver, WindowLi
void initState() {
super.initState();

_appImplementations = NeonProvider.of<Iterable<AppImplementation>>(context);
_appImplementations = NeonProvider.of<BuiltSet<AppImplementation>>(context);
_globalOptions = NeonProvider.of<GlobalOptions>(context);
_accountsBloc = NeonProvider.of<AccountsBloc>(context);

Expand Down Expand Up @@ -114,7 +115,7 @@ class _NeonAppState extends State<NeonApp> with WidgetsBindingObserver, WindowLi
return;
}

final allAppImplementations = NeonProvider.of<Iterable<AppImplementation>>(context);
final allAppImplementations = NeonProvider.of<BuiltSet<AppImplementation>>(context);
final app = allAppImplementations.tryFind(AppIDs.notifications) as NotificationsAppInterface?;

if (app == null) {
Expand All @@ -130,7 +131,7 @@ class _NeonAppState extends State<NeonApp> with WidgetsBindingObserver, WindowLi
}
_accountsBloc.setActiveAccount(account);

final allAppImplementations = NeonProvider.of<Iterable<AppImplementation>>(context);
final allAppImplementations = NeonProvider.of<BuiltSet<AppImplementation>>(context);

final notificationsApp = allAppImplementations.tryFind(AppIDs.notifications) as NotificationsAppInterface?;
if (notificationsApp != null) {
Expand Down
5 changes: 3 additions & 2 deletions packages/neon_framework/lib/src/blocs/accounts.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:convert';

import 'package:built_collection/built_collection.dart';
import 'package:collection/collection.dart';
import 'package:flutter/foundation.dart';
import 'package:meta/meta.dart';
Expand Down Expand Up @@ -29,7 +30,7 @@ abstract interface class AccountsBloc implements Disposable {
@internal
factory AccountsBloc(
GlobalOptions globalOptions,
Iterable<AppImplementation> allAppImplementations,
BuiltSet<AppImplementation> allAppImplementations,
) =>
_AccountsBloc(
globalOptions,
Expand Down Expand Up @@ -203,7 +204,7 @@ class _AccountsBloc extends Bloc implements AccountsBloc {
}

final GlobalOptions globalOptions;
final Iterable<AppImplementation> allAppImplementations;
final BuiltSet<AppImplementation> allAppImplementations;

final accountsOptions = AccountCache<AccountOptions>();
final appsBlocs = AccountCache<AppsBloc>();
Expand Down
12 changes: 6 additions & 6 deletions packages/neon_framework/lib/src/blocs/apps.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ abstract class AppsBloc implements InteractiveBloc {
CapabilitiesBloc capabilitiesBloc,
AccountsBloc accountsBloc,
Account account,
Iterable<AppImplementation> allAppImplementations,
BuiltSet<AppImplementation> allAppImplementations,
) =>
_AppsBloc(
capabilitiesBloc,
Expand All @@ -45,7 +45,7 @@ abstract class AppsBloc implements InteractiveBloc {
/// 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<BuiltSet<AppImplementation>>> get appImplementations;

/// The interface of the notifications app.
BehaviorSubject<Result<NotificationsAppInterface?>> get notificationsAppImplementation;
Expand Down Expand Up @@ -213,13 +213,13 @@ class _AppsBloc extends InteractiveBloc implements AppsBloc {
return null;
}

Iterable<AppImplementation> filteredAppImplementations(Iterable<String> appIds) =>
allAppImplementations.where((a) => appIds.contains(a.id));
BuiltSet<AppImplementation> filteredAppImplementations(Iterable<String> appIds) =>
BuiltSet(allAppImplementations.where((a) => appIds.contains(a.id)));

final CapabilitiesBloc capabilitiesBloc;
final AccountsBloc accountsBloc;
final Account account;
final Iterable<AppImplementation> allAppImplementations;
final BuiltSet<AppImplementation> allAppImplementations;
final apps = BehaviorSubject<Result<BuiltList<core.NavigationEntry>>>();

@override
Expand All @@ -238,7 +238,7 @@ class _AppsBloc extends InteractiveBloc implements AppsBloc {
BehaviorSubject<AppImplementation> activeApp = BehaviorSubject();

@override
BehaviorSubject<Result<Iterable<AppImplementation<Bloc, AppImplementationOptions>>>> appImplementations =
BehaviorSubject<Result<BuiltSet<AppImplementation<Bloc, AppImplementationOptions>>>> appImplementations =
BehaviorSubject();

@override
Expand Down
3 changes: 2 additions & 1 deletion packages/neon_framework/lib/src/pages/home.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:async';

import 'package:built_collection/built_collection.dart';
import 'package:flutter/material.dart';
import 'package:meta/meta.dart';
import 'package:neon_framework/l10n/localizations.dart';
Expand Down Expand Up @@ -107,7 +108,7 @@ class _HomePageState extends State<HomePage> {
if (unifiedSearchEnabledSnapshot.data ?? false) {
return const NeonUnifiedSearchResults();
}
return ResultBuilder<Iterable<AppImplementation>>.behaviorSubject(
return ResultBuilder<BuiltSet<AppImplementation>>.behaviorSubject(
subject: _appsBloc.appImplementations,
builder: (context, appImplementations) {
if (!appImplementations.hasData) {
Expand Down
5 changes: 3 additions & 2 deletions packages/neon_framework/lib/src/pages/settings.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:built_collection/built_collection.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
Expand Down Expand Up @@ -84,7 +85,7 @@ class _SettingsPageState extends State<SettingsPage> {
Widget build(BuildContext context) {
final globalOptions = NeonProvider.of<GlobalOptions>(context);
final accountsBloc = NeonProvider.of<AccountsBloc>(context);
final appImplementations = NeonProvider.of<Iterable<AppImplementation>>(context);
final appImplementations = NeonProvider.of<BuiltSet<AppImplementation>>(context);
final branding = Branding.of(context);

final appBar = AppBar(
Expand Down Expand Up @@ -415,7 +416,7 @@ class _SettingsPageState extends State<SettingsPage> {
SettingsExportHelper _buildSettingsExportHelper(BuildContext context) {
final globalOptions = NeonProvider.of<GlobalOptions>(context);
final accountsBloc = NeonProvider.of<AccountsBloc>(context);
final appImplementations = NeonProvider.of<Iterable<AppImplementation>>(context);
final appImplementations = NeonProvider.of<BuiltSet<AppImplementation>>(context);

return SettingsExportHelper(
exportables: {
Expand Down
3 changes: 2 additions & 1 deletion packages/neon_framework/lib/src/router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import 'dart:async';

import 'package:built_collection/built_collection.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
Expand Down Expand Up @@ -464,7 +465,7 @@ class AppImplementationSettingsRoute extends GoRouteData {

@override
Widget build(BuildContext context, GoRouterState state) {
final appImplementations = NeonProvider.of<Iterable<AppImplementation>>(context);
final appImplementations = NeonProvider.of<BuiltSet<AppImplementation>>(context);
final appImplementation = appImplementations.tryFind(appid)!;

return AppImplementationSettingsPage(appImplementation: appImplementation);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';

import 'package:built_collection/built_collection.dart';
import 'package:meta/meta.dart';
import 'package:neon_framework/src/blocs/accounts.dart';
import 'package:neon_framework/src/models/account.dart' show Account;
import 'package:neon_framework/src/models/app_implementation.dart';
import 'package:neon_framework/src/settings/models/exportable.dart';
import 'package:neon_framework/src/settings/models/option.dart';
import 'package:neon_framework/src/storage/keys.dart';

import 'package:neon_framework/src/utils/findable.dart';

/// Helper class to export all [Option]s.
Expand Down Expand Up @@ -84,7 +84,7 @@ class AppImplementationsExporter implements Exportable {
const AppImplementationsExporter(this.appImplementations);

/// List of apps to export.
final Iterable<AppImplementation> appImplementations;
final BuiltSet<AppImplementation> appImplementations;

/// Key the exported value will be stored at.
static final _key = StorageKeys.apps.value;
Expand Down
3 changes: 2 additions & 1 deletion packages/neon_framework/lib/src/widgets/app_bar.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:async';

import 'package:built_collection/built_collection.dart';
import 'package:flutter/material.dart';
import 'package:meta/meta.dart';
import 'package:neon_framework/l10n/localizations.dart';
Expand Down Expand Up @@ -64,7 +65,7 @@ class _NeonAppBarState extends State<NeonAppBar> {
}

@override
Widget build(BuildContext context) => ResultBuilder<Iterable<AppImplementation>>.behaviorSubject(
Widget build(BuildContext context) => ResultBuilder<BuiltSet<AppImplementation>>.behaviorSubject(
subject: appsBloc.appImplementations,
builder: (context, appImplementations) => StreamBuilder(
stream: appsBloc.activeApp,
Expand Down
5 changes: 3 additions & 2 deletions packages/neon_framework/test/drawer_test.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:async';

import 'package:built_collection/built_collection.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
Expand Down Expand Up @@ -36,7 +37,7 @@ void main() {
),
);

final appImplementations = BehaviorSubject<Result<Iterable<AppImplementation>>>();
final appImplementations = BehaviorSubject<Result<BuiltSet<AppImplementation>>>();
final activeApp = BehaviorSubject<AppImplementation>();
final appsBloc = MockAppsBloc();
when(() => appsBloc.activeApp).thenAnswer((_) => activeApp);
Expand Down Expand Up @@ -69,7 +70,7 @@ void main() {
expect(find.byType(NavigationDrawerDestination), findsOne);

activeApp.add(appImplementation);
appImplementations.add(Result.success([appImplementation]));
appImplementations.add(Result.success(BuiltSet({appImplementation})));

await tester.pumpAndSettle();

Expand Down
5 changes: 3 additions & 2 deletions packages/neon_framework/test/settings_export_test.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:convert';
import 'dart:typed_data';

import 'package:built_collection/built_collection.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
import 'package:neon_framework/src/settings/utils/settings_export_helper.dart';
Expand All @@ -10,14 +11,14 @@ import 'package:rxdart/rxdart.dart';
void main() {
group('Exporter', () {
test('AccountsBlocExporter', () {
var exporter = const AppImplementationsExporter([]);
var exporter = AppImplementationsExporter(BuiltSet());

var export = exporter.export();
expect(Map.fromEntries([export]), {'app': <String, dynamic>{}});

final fakeApp = MockAppImplementation();
final fakeOptions = MockAppImplementationOptions();
exporter = AppImplementationsExporter([fakeApp]);
exporter = AppImplementationsExporter(BuiltSet({fakeApp}));

const appValue = MapEntry('appID', 'value');
const appExport = {
Expand Down

0 comments on commit a70b125

Please sign in to comment.