Browse Source

Merge pull request #654 from nextcloud/refactor/sharedPreferences

Refactor/shared preferences
pull/664/head
Nikolas Rimikis 1 year ago committed by GitHub
parent
commit
db51fa1e16
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      packages/app/integration_test/screenshot_test.dart
  2. 16
      packages/app/lib/apps.dart
  3. 2
      packages/app/lib/main.dart
  4. 12
      packages/app/pubspec.lock
  5. 3
      packages/app/pubspec.yaml
  6. 19
      packages/neon/neon/lib/neon.dart
  7. 7
      packages/neon/neon/lib/src/blocs/accounts.dart
  8. 18
      packages/neon/neon/lib/src/blocs/first_launch.dart
  9. 5
      packages/neon/neon/lib/src/blocs/push_notifications.dart
  10. 19
      packages/neon/neon/lib/src/models/app_implementation.dart
  11. 7
      packages/neon/neon/lib/src/models/notifications_interface.dart
  12. 47
      packages/neon/neon/lib/src/settings/models/storage.dart
  13. 5
      packages/neon/neon/lib/src/utils/global_options.dart
  14. 7
      packages/neon/neon/lib/src/utils/push_utils.dart
  15. 30
      packages/neon/neon/test/app_implementation_test.dart
  16. 14
      packages/neon/neon/test/storage_test.dart
  17. 14
      packages/neon/neon_files/lib/neon_files.dart
  18. 14
      packages/neon/neon_news/lib/neon_news.dart
  19. 14
      packages/neon/neon_notes/lib/neon_notes.dart
  20. 14
      packages/neon/neon_notifications/lib/neon_notifications.dart

2
packages/app/integration_test/screenshot_test.dart

@ -20,7 +20,7 @@ Future runTestApp(
final Account? account,
}) async {
await runNeon(
getAppImplementations: getAppImplementations,
appImplementations: appImplementations,
theme: neonTheme,
bindingOverride: binding,
account: account,

16
packages/app/lib/apps.dart

@ -3,14 +3,10 @@ import 'package:neon_files/neon_files.dart';
import 'package:neon_news/neon_news.dart';
import 'package:neon_notes/neon_notes.dart';
import 'package:neon_notifications/neon_notifications.dart';
import 'package:shared_preferences/shared_preferences.dart';
List<AppImplementation> getAppImplementations(
final SharedPreferences sharedPreferences,
) =>
[
FilesApp(sharedPreferences),
NewsApp(sharedPreferences),
NotesApp(sharedPreferences),
NotificationsApp(sharedPreferences),
];
final List<AppImplementation> appImplementations = [
FilesApp(),
NewsApp(),
NotesApp(),
NotificationsApp(),
];

2
packages/app/lib/main.dart

@ -4,7 +4,7 @@ import 'package:neon/neon.dart';
Future main() async {
await runNeon(
getAppImplementations: getAppImplementations,
appImplementations: appImplementations,
theme: neonTheme,
);
}

12
packages/app/pubspec.lock

@ -349,10 +349,10 @@ packages:
dependency: transitive
description:
name: flutter_local_notifications
sha256: "3cc40fe8c50ab8383f3e053a499f00f975636622ecdc8e20a77418ece3b1e975"
sha256: "3002092e5b8ce2f86c3361422e52e6db6776c23ee21e0b2f71b892bf4259ef04"
url: "https://pub.dev"
source: hosted
version: "15.1.0+1"
version: "15.1.1"
flutter_local_notifications_linux:
dependency: transitive
description:
@ -383,7 +383,7 @@ packages:
source: hosted
version: "0.6.17+1"
flutter_native_splash:
dependency: "direct main"
dependency: transitive
description:
name: flutter_native_splash
sha256: ecff62b3b893f2f665de7e4ad3de89f738941fcfcaaba8ee601e749efafa4698
@ -1044,7 +1044,7 @@ packages:
source: hosted
version: "3.3.0"
shared_preferences:
dependency: "direct main"
dependency: "direct dev"
description:
name: shared_preferences
sha256: "0344316c947ffeb3a529eac929e1978fcd37c26be4e8468628bac399365a3ca1"
@ -1443,10 +1443,10 @@ packages:
dependency: transitive
description:
name: webview_flutter
sha256: "789d52bd789373cc1e100fb634af2127e86c99cf9abde09499743270c5de8d00"
sha256: "04a0782fb058b7c71f2048935583488f4d32e9147ca403abc4e58f1de9964629"
url: "https://pub.dev"
source: hosted
version: "4.2.2"
version: "4.2.3"
webview_flutter_android:
dependency: transitive
description:

3
packages/app/pubspec.yaml

@ -9,7 +9,6 @@ environment:
dependencies:
flutter:
sdk: flutter
flutter_native_splash: ^2.3.2
flutter_svg: ^2.0.7
neon:
git:
@ -31,7 +30,6 @@ dependencies:
git:
url: https://github.com/nextcloud/neon
path: packages/neon/neon_notifications
shared_preferences: ^2.2.0
dev_dependencies:
flutter_test:
@ -43,6 +41,7 @@ dev_dependencies:
git:
url: https://github.com/nextcloud/neon
path: packages/neon_lints
shared_preferences: ^2.2.0
flutter:
uses-material-design: true

19
packages/neon/neon/lib/neon.dart

@ -10,16 +10,16 @@ import 'package:neon/src/blocs/push_notifications.dart';
import 'package:neon/src/models/account.dart';
import 'package:neon/src/models/app_implementation.dart';
import 'package:neon/src/platform/platform.dart';
import 'package:neon/src/settings/models/storage.dart';
import 'package:neon/src/theme/neon.dart';
import 'package:neon/src/utils/global_options.dart';
import 'package:neon/src/utils/request_manager.dart';
import 'package:neon/src/utils/user_agent.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
Future runNeon({
required final Iterable<AppImplementation> Function(SharedPreferences) getAppImplementations,
required final Iterable<AppImplementation> appImplementations,
required final NeonTheme theme,
@visibleForTesting final WidgetsBinding? bindingOverride,
@visibleForTesting final Account? account,
@ -29,24 +29,20 @@ Future runNeon({
final binding = bindingOverride ?? WidgetsFlutterBinding.ensureInitialized();
FlutterNativeSplash.preserve(widgetsBinding: binding);
final sharedPreferences = await SharedPreferences.getInstance();
await NeonPlatform.setup();
await RequestManager.instance.initCache();
final allAppImplementations = getAppImplementations(sharedPreferences);
await AppStorage.init();
final packageInfo = await PackageInfo.fromPlatform();
buildUserAgent(packageInfo);
final globalOptions = GlobalOptions(
sharedPreferences,
packageInfo,
);
final accountsBloc = AccountsBloc(
sharedPreferences,
globalOptions,
allAppImplementations,
appImplementations,
);
if (account != null) {
accountsBloc
@ -55,11 +51,9 @@ Future runNeon({
}
final pushNotificationsBloc = PushNotificationsBloc(
accountsBloc,
sharedPreferences,
globalOptions,
);
final firstLaunchBloc = FirstLaunchBloc(
sharedPreferences,
disabled: firstLaunchDisabled,
);
final nextPushBloc = NextPushBloc(
@ -71,9 +65,6 @@ Future runNeon({
runApp(
MultiProvider(
providers: [
Provider<SharedPreferences>(
create: (final _) => sharedPreferences,
),
Provider<GlobalOptions>(
create: (final _) => globalOptions,
),
@ -90,7 +81,7 @@ Future runNeon({
create: (final _) => nextPushBloc,
),
Provider<Iterable<AppImplementation>>(
create: (final _) => allAppImplementations,
create: (final _) => appImplementations,
),
Provider<PackageInfo>(
create: (final _) => packageInfo,

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

@ -14,7 +14,6 @@ import 'package:neon/src/settings/models/storage.dart';
import 'package:neon/src/utils/account_options.dart';
import 'package:neon/src/utils/global_options.dart';
import 'package:rxdart/rxdart.dart';
import 'package:shared_preferences/shared_preferences.dart';
const _keyAccounts = 'accounts';
@ -56,7 +55,6 @@ abstract interface class AccountsBlocStates {
class AccountsBloc extends Bloc implements AccountsBlocEvents, AccountsBlocStates {
AccountsBloc(
this._sharedPreferences,
this._globalOptions,
this._allAppImplementations,
) {
@ -96,8 +94,7 @@ class AccountsBloc extends Bloc implements AccountsBlocEvents, AccountsBlocState
}
}
late final AppStorage _storage = AppStorage('accounts', _sharedPreferences);
final SharedPreferences _sharedPreferences;
late final AppStorage _storage = AppStorage('accounts');
final GlobalOptions _globalOptions;
final Iterable<AppImplementation> _allAppImplementations;
final _keyLastUsedAccount = 'last-used-account';
@ -213,7 +210,7 @@ class AccountsBloc extends Bloc implements AccountsBlocEvents, AccountsBlocState
/// Use [activeOptions] to get them for the [activeAccount].
AccountSpecificOptions getOptionsFor(final Account account) =>
_accountsOptions[account.id] ??= AccountSpecificOptions(
AppStorage('accounts-${account.id}', _sharedPreferences),
AppStorage('accounts-${account.id}'),
getAppsBlocFor(account),
);

18
packages/neon/neon/lib/src/blocs/first_launch.dart

@ -2,8 +2,8 @@ import 'dart:async';
import 'package:meta/meta.dart';
import 'package:neon/src/bloc/bloc.dart';
import 'package:neon/src/settings/models/storage.dart';
import 'package:rxdart/rxdart.dart';
import 'package:shared_preferences/shared_preferences.dart';
abstract class FirstLaunchBlocEvents {}
@ -11,20 +11,20 @@ abstract class FirstLaunchBlocStates {
BehaviorSubject get onFirstLaunch;
}
@immutable
@internal
class FirstLaunchBloc extends Bloc implements FirstLaunchBlocEvents, FirstLaunchBlocStates {
FirstLaunchBloc(
this._sharedPreferences, {
FirstLaunchBloc({
final bool disabled = false,
}) {
if (!disabled && !_sharedPreferences.containsKey(_keyFirstLaunch)) {
}) : _storage = AppStorage(_keyFirstLaunch) {
if (!disabled && !_storage.containsKey(_keyFirstLaunch)) {
onFirstLaunch.add(null);
unawaited(_sharedPreferences.setBool(_keyFirstLaunch, false));
unawaited(_storage.setBool(_keyFirstLaunch, false));
}
}
final SharedPreferences _sharedPreferences;
final _keyFirstLaunch = 'first-launch';
final AppStorage _storage;
static const _keyFirstLaunch = 'first-launch';
@override
void dispose() {
@ -32,5 +32,5 @@ class FirstLaunchBloc extends Bloc implements FirstLaunchBlocEvents, FirstLaunch
}
@override
BehaviorSubject onFirstLaunch = BehaviorSubject();
final BehaviorSubject onFirstLaunch = BehaviorSubject();
}

5
packages/neon/neon/lib/src/blocs/push_notifications.dart

@ -13,7 +13,6 @@ import 'package:neon/src/settings/models/storage.dart';
import 'package:neon/src/utils/global_options.dart';
import 'package:neon/src/utils/push_utils.dart';
import 'package:nextcloud/nextcloud.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:unifiedpush/unifiedpush.dart';
abstract class PushNotificationsBlocEvents {}
@ -26,7 +25,6 @@ abstract class PushNotificationsBlocStates {
class PushNotificationsBloc extends Bloc implements PushNotificationsBlocEvents, PushNotificationsBlocStates {
PushNotificationsBloc(
this._accountsBloc,
this._sharedPreferences,
this._globalOptions,
) {
if (NeonPlatform.instance.canUsePushNotifications) {
@ -39,8 +37,7 @@ class PushNotificationsBloc extends Bloc implements PushNotificationsBlocEvents,
}
final AccountsBloc _accountsBloc;
final SharedPreferences _sharedPreferences;
late final _storage = AppStorage(AppIDs.notifications, _sharedPreferences);
late final _storage = AppStorage(AppIDs.notifications);
final GlobalOptions _globalOptions;
final _notificationsController = StreamController<PushNotification>();

19
packages/neon/neon/lib/src/models/app_implementation.dart

@ -2,6 +2,7 @@ import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:go_router/go_router.dart';
import 'package:meta/meta.dart';
import 'package:neon/l10n/localizations.dart';
import 'package:neon/src/bloc/bloc.dart';
import 'package:neon/src/blocs/accounts.dart';
@ -11,15 +12,10 @@ import 'package:neon/src/settings/models/storage.dart';
import 'package:neon/src/widgets/drawer_destination.dart';
import 'package:provider/provider.dart';
import 'package:rxdart/rxdart.dart';
import 'package:shared_preferences/shared_preferences.dart';
@immutable
abstract class AppImplementation<T extends Bloc, R extends NextcloudAppOptions> {
AppImplementation(
final SharedPreferences sharedPreferences,
) {
final storage = AppStorage('app-$id', sharedPreferences);
options = buildOptions(storage);
}
AppImplementation();
String get id;
LocalizationsDelegate get localizationsDelegate;
@ -28,10 +24,11 @@ abstract class AppImplementation<T extends Bloc, R extends NextcloudAppOptions>
String nameFromLocalization(final AppLocalizations localizations) => localizations.appImplementationName(id);
String name(final BuildContext context) => nameFromLocalization(AppLocalizations.of(context));
late final R options;
@protected
R buildOptions(final AppStorage storage);
late final AppStorage storage = AppStorage('app-$id');
@mustBeOverridden
R get options;
final Map<String, T> _blocs = {};
@ -118,7 +115,7 @@ abstract class AppImplementation<T extends Bloc, R extends NextcloudAppOptions>
/// A custom theme that will be injected into the widget tree.
///
/// You can later acess it through `Theme.of(context).extension<ThemeName>()`.
ThemeExtension? theme;
final ThemeExtension? theme = null;
}
extension AppImplementationFind on Iterable<AppImplementation> {

7
packages/neon/neon/lib/src/models/notifications_interface.dart

@ -1,10 +1,15 @@
import 'package:meta/meta.dart';
import 'package:neon/src/bloc/bloc.dart';
import 'package:neon/src/models/app_implementation.dart';
import 'package:neon/src/settings/models/nextcloud_app_options.dart';
abstract interface class NotificationsAppInterface<T extends NotificationsBlocInterface,
R extends NotificationsOptionsInterface> extends AppImplementation<T, R> {
NotificationsAppInterface(super.sharedPreferences);
NotificationsAppInterface();
@override
@mustBeOverridden
R get options => throw UnimplementedError();
}
abstract interface class NotificationsBlocInterface extends InteractiveBloc {

47
packages/neon/neon/lib/src/settings/models/storage.dart

@ -1,3 +1,4 @@
import 'package:meta/meta.dart';
import 'package:shared_preferences/shared_preferences.dart';
abstract interface class SettingsStorage {
@ -14,35 +15,55 @@ abstract interface class SettingsStorage {
}
class AppStorage implements SettingsStorage {
AppStorage(
this._id,
this._sharedPreferences,
);
AppStorage(this._id);
final String _id;
final SharedPreferences _sharedPreferences;
/// Shared preferences instance.
///
/// Use [reqireDatabase] to access it.
/// Make sure it has been initialized wiht [init] before.
static SharedPreferences? _sharedPreferences;
/// Sets up the [SharedPreferences] instance.
///
/// Required to be called before accessing [reqireDatabase].
static Future init() async {
_sharedPreferences = await SharedPreferences.getInstance();
}
@visibleForTesting
static SharedPreferences get reqireDatabase {
if (_sharedPreferences == null) {
throw StateError(
'AppStorage has not been initialized yet. Please make sure AppStorage.init() has been called before and completed.',
);
}
return _sharedPreferences!;
}
String _formatKey(final String key) => '$_id-$key';
bool containsKey(final String key) => _sharedPreferences.containsKey(_formatKey(key));
bool containsKey(final String key) => reqireDatabase.containsKey(_formatKey(key));
@override
Future<bool> remove(final String key) => _sharedPreferences.remove(_formatKey(key));
Future<bool> remove(final String key) => reqireDatabase.remove(_formatKey(key));
@override
String? getString(final String key) => _sharedPreferences.getString(_formatKey(key));
String? getString(final String key) => reqireDatabase.getString(_formatKey(key));
@override
Future setString(final String key, final String value) => _sharedPreferences.setString(_formatKey(key), value);
Future setString(final String key, final String value) => reqireDatabase.setString(_formatKey(key), value);
@override
bool? getBool(final String key) => _sharedPreferences.getBool(_formatKey(key));
bool? getBool(final String key) => reqireDatabase.getBool(_formatKey(key));
@override
Future setBool(final String key, final bool value) => _sharedPreferences.setBool(_formatKey(key), value);
Future setBool(final String key, final bool value) => reqireDatabase.setBool(_formatKey(key), value);
List<String>? getStringList(final String key) => _sharedPreferences.getStringList(_formatKey(key));
List<String>? getStringList(final String key) => reqireDatabase.getStringList(_formatKey(key));
Future setStringList(final String key, final List<String> value) =>
_sharedPreferences.setStringList(_formatKey(key), value);
reqireDatabase.setStringList(_formatKey(key), value);
}

5
packages/neon/neon/lib/src/utils/global_options.dart

@ -11,7 +11,6 @@ import 'package:neon/src/settings/models/storage.dart';
import 'package:neon/src/settings/models/toggle_option.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:shared_preferences/shared_preferences.dart';
const unifiedPushNextPushID = 'org.unifiedpush.distributor.nextpush';
@ -19,7 +18,6 @@ const unifiedPushNextPushID = 'org.unifiedpush.distributor.nextpush';
@immutable
class GlobalOptions {
GlobalOptions(
this._sharedPreferences,
this._packageInfo,
) {
pushNotificationsEnabled.addListener(_pushNotificationsEnabledListener);
@ -51,8 +49,7 @@ class GlobalOptions {
}
}
final SharedPreferences _sharedPreferences;
late final AppStorage _storage = AppStorage('global', _sharedPreferences);
late final AppStorage _storage = AppStorage('global');
final PackageInfo _packageInfo;
late final _distributorsMap = <String, String Function(BuildContext)>{

7
packages/neon/neon/lib/src/utils/push_utils.dart

@ -18,7 +18,6 @@ import 'package:neon/src/theme/colors.dart';
import 'package:neon/src/utils/global.dart';
import 'package:neon/src/utils/localizations.dart';
import 'package:nextcloud/nextcloud.dart';
import 'package:shared_preferences/shared_preferences.dart';
@internal
@immutable
@ -71,9 +70,9 @@ class PushUtils {
}
},
);
final sharedPreferences = await SharedPreferences.getInstance();
await AppStorage.init();
final keypair = await loadRSAKeypair(AppStorage(AppIDs.notifications, sharedPreferences));
final keypair = await loadRSAKeypair(AppStorage(AppIDs.notifications));
for (final message in Uri(query: utf8.decode(messages)).queryParameters.values) {
final data = json.decode(message) as Map<String, dynamic>;
@ -99,7 +98,7 @@ class PushUtils {
NotificationsNotification? notification;
AndroidBitmap<Object>? largeIconBitmap;
try {
accounts = loadAccounts(AppStorage('accounts', sharedPreferences));
accounts = loadAccounts(AppStorage('accounts'));
account = accounts.tryFind(instance);
if (account != null) {
notification =

30
packages/neon/neon/test/app_implementation_test.dart

@ -0,0 +1,30 @@
import 'package:mocktail/mocktail.dart';
import 'package:neon/src/models/app_implementation.dart';
import 'package:test/test.dart';
// ignore: missing_override_of_must_be_overridden
class AppImplementationMock extends Mock implements AppImplementation {}
void main() {
group('group name', () {
test('AccountFind', () {
final app1 = AppImplementationMock();
final app2 = AppImplementationMock();
final apps = {
app1,
app2,
};
when(() => app1.id).thenReturn('app1');
when(() => app2.id).thenReturn('app2');
expect(apps.tryFind(null), isNull);
expect(apps.tryFind('invalidID'), isNull);
expect(apps.tryFind(app2.id), equals(app2));
expect(() => apps.find('invalidID'), throwsA(isA<StateError>()));
expect(apps.find(app2.id), equals(app2));
});
});
}

14
packages/neon/neon/test/storage_test.dart

@ -0,0 +1,14 @@
import 'package:neon/src/settings/models/storage.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:test/test.dart';
void main() {
test('AppStorage', () async {
expect(() => AppStorage.reqireDatabase, throwsA(isA<StateError>()));
SharedPreferences.setMockInitialValues({});
await AppStorage.init();
expect(AppStorage.reqireDatabase, isA<SharedPreferences>());
});
}

14
packages/neon/neon_files/lib/neon_files.dart

@ -44,19 +44,19 @@ part 'widgets/browser_view.dart';
part 'widgets/file_preview.dart';
class FilesApp extends AppImplementation<FilesBloc, FilesAppSpecificOptions> {
FilesApp(super.sharedPreferences);
FilesApp();
@override
String id = AppIDs.files;
final String id = AppIDs.files;
@override
LocalizationsDelegate localizationsDelegate = AppLocalizations.delegate;
final LocalizationsDelegate localizationsDelegate = AppLocalizations.delegate;
@override
List<Locale> supportedLocales = AppLocalizations.supportedLocales;
final List<Locale> supportedLocales = AppLocalizations.supportedLocales;
@override
FilesAppSpecificOptions buildOptions(final AppStorage storage) => FilesAppSpecificOptions(storage);
late final FilesAppSpecificOptions options = FilesAppSpecificOptions(storage);
@override
FilesBloc buildBloc(final Account account) => FilesBloc(
@ -65,8 +65,8 @@ class FilesApp extends AppImplementation<FilesBloc, FilesAppSpecificOptions> {
);
@override
Widget get page => const FilesMainPage();
final Widget page = const FilesMainPage();
@override
RouteBase get route => $filesAppRoute;
final RouteBase route = $filesAppRoute;
}

14
packages/neon/neon_news/lib/neon_news.dart

@ -52,19 +52,19 @@ part 'widgets/folder_view.dart';
part 'widgets/folders_view.dart';
class NewsApp extends AppImplementation<NewsBloc, NewsAppSpecificOptions> {
NewsApp(super.sharedPreferences);
NewsApp();
@override
String id = AppIDs.news;
final String id = AppIDs.news;
@override
LocalizationsDelegate localizationsDelegate = AppLocalizations.delegate;
final LocalizationsDelegate localizationsDelegate = AppLocalizations.delegate;
@override
List<Locale> supportedLocales = AppLocalizations.supportedLocales;
final List<Locale> supportedLocales = AppLocalizations.supportedLocales;
@override
NewsAppSpecificOptions buildOptions(final AppStorage storage) => NewsAppSpecificOptions(storage);
late final NewsAppSpecificOptions options = NewsAppSpecificOptions(storage);
@override
NewsBloc buildBloc(final Account account) => NewsBloc(
@ -73,10 +73,10 @@ class NewsApp extends AppImplementation<NewsBloc, NewsAppSpecificOptions> {
);
@override
Widget get page => const NewsMainPage();
final Widget page = const NewsMainPage();
@override
RouteBase get route => $newsAppRoute;
final RouteBase route = $newsAppRoute;
@override
BehaviorSubject<int> getUnreadCounter(final NewsBloc bloc) => bloc.unreadCounter;

14
packages/neon/neon_notes/lib/neon_notes.dart

@ -42,19 +42,19 @@ part 'widgets/notes_floating_action_button.dart';
part 'widgets/notes_view.dart';
class NotesApp extends AppImplementation<NotesBloc, NotesAppSpecificOptions> {
NotesApp(super.sharedPreferences);
NotesApp();
@override
String id = AppIDs.notes;
final String id = AppIDs.notes;
@override
List<Locale> supportedLocales = AppLocalizations.supportedLocales;
final List<Locale> supportedLocales = AppLocalizations.supportedLocales;
@override
LocalizationsDelegate localizationsDelegate = AppLocalizations.delegate;
final LocalizationsDelegate localizationsDelegate = AppLocalizations.delegate;
@override
NotesAppSpecificOptions buildOptions(final AppStorage storage) => NotesAppSpecificOptions(storage);
late final NotesAppSpecificOptions options = NotesAppSpecificOptions(storage);
@override
NotesBloc buildBloc(final Account account) => NotesBloc(
@ -63,8 +63,8 @@ class NotesApp extends AppImplementation<NotesBloc, NotesAppSpecificOptions> {
);
@override
Widget get page => const NotesMainPage();
final Widget page = const NotesMainPage();
@override
RouteBase get route => $notesAppRoute;
final RouteBase route = $notesAppRoute;
}

14
packages/neon/neon_notifications/lib/neon_notifications.dart

@ -22,19 +22,19 @@ part 'pages/main.dart';
class NotificationsApp extends AppImplementation<NotificationsBloc, NotificationsAppSpecificOptions>
implements NotificationsAppInterface<NotificationsBloc, NotificationsAppSpecificOptions> {
NotificationsApp(super.sharedPreferences);
NotificationsApp();
@override
String id = AppIDs.notifications;
final String id = AppIDs.notifications;
@override
LocalizationsDelegate localizationsDelegate = AppLocalizations.delegate;
final LocalizationsDelegate localizationsDelegate = AppLocalizations.delegate;
@override
List<Locale> supportedLocales = AppLocalizations.supportedLocales;
final List<Locale> supportedLocales = AppLocalizations.supportedLocales;
@override
NotificationsAppSpecificOptions buildOptions(final AppStorage storage) => NotificationsAppSpecificOptions(storage);
late final NotificationsAppSpecificOptions options = NotificationsAppSpecificOptions(storage);
@override
NotificationsBloc buildBloc(final Account account) => NotificationsBloc(
@ -43,10 +43,10 @@ class NotificationsApp extends AppImplementation<NotificationsBloc, Notification
);
@override
Widget get page => const NotificationsMainPage();
final Widget page = const NotificationsMainPage();
@override
RouteBase get route => $notificationsAppRoute;
final RouteBase route = $notificationsAppRoute;
@override
BehaviorSubject<int> getUnreadCounter(final NotificationsBloc bloc) => bloc.unreadCounter;

Loading…
Cancel
Save