From 1829bf1b7a11f6c2f510eefcde636c7aa1349a4d Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Tue, 5 Sep 2023 12:05:14 +0200 Subject: [PATCH 1/3] fix(neon,neon_files,neon_news,neon_notes): properly dispoe TextEditingController Signed-off-by: Nikolas Rimikis --- .../neon/neon/lib/src/utils/rename_dialog.dart | 14 +++++++++++++- .../neon/neon_files/lib/dialogs/create_folder.dart | 6 ++++++ packages/neon/neon_news/lib/dialogs/add_feed.dart | 6 ++++++ .../neon/neon_news/lib/dialogs/create_folder.dart | 6 ++++++ .../neon/neon_notes/lib/dialogs/create_note.dart | 6 ++++++ packages/neon/neon_notes/lib/pages/note.dart | 9 +++++++-- 6 files changed, 44 insertions(+), 3 deletions(-) diff --git a/packages/neon/neon/lib/src/utils/rename_dialog.dart b/packages/neon/neon/lib/src/utils/rename_dialog.dart index 24ec4876..bef84826 100644 --- a/packages/neon/neon/lib/src/utils/rename_dialog.dart +++ b/packages/neon/neon/lib/src/utils/rename_dialog.dart @@ -34,7 +34,19 @@ class _RenameDialog extends StatefulWidget { class _RenameDialogState extends State<_RenameDialog> { final formKey = GlobalKey(); - late final controller = TextEditingController()..text = widget.value; + final controller = TextEditingController(); + + @override + void initState() { + controller.text = widget.value; + super.initState(); + } + + @override + void dispose() { + controller.dispose(); + super.dispose(); + } void submit() { if (formKey.currentState!.validate()) { diff --git a/packages/neon/neon_files/lib/dialogs/create_folder.dart b/packages/neon/neon_files/lib/dialogs/create_folder.dart index fab90b8e..d2d628f3 100644 --- a/packages/neon/neon_files/lib/dialogs/create_folder.dart +++ b/packages/neon/neon_files/lib/dialogs/create_folder.dart @@ -14,6 +14,12 @@ class _FilesCreateFolderDialogState extends State { final controller = TextEditingController(); + @override + void dispose() { + controller.dispose(); + super.dispose(); + } + void submit() { if (formKey.currentState!.validate()) { Navigator.of(context).pop(controller.text.split('/')); diff --git a/packages/neon/neon_news/lib/dialogs/add_feed.dart b/packages/neon/neon_news/lib/dialogs/add_feed.dart index c1f4fb98..4c640a29 100644 --- a/packages/neon/neon_news/lib/dialogs/add_feed.dart +++ b/packages/neon/neon_news/lib/dialogs/add_feed.dart @@ -42,6 +42,12 @@ class _NewsAddFeedDialogState extends State { ); } + @override + void dispose() { + controller.dispose(); + super.dispose(); + } + @override Widget build(final BuildContext context) => ResultBuilder>.behaviorSubject( stream: widget.bloc.folders, diff --git a/packages/neon/neon_news/lib/dialogs/create_folder.dart b/packages/neon/neon_news/lib/dialogs/create_folder.dart index 18c9106c..be4b2ca9 100644 --- a/packages/neon/neon_news/lib/dialogs/create_folder.dart +++ b/packages/neon/neon_news/lib/dialogs/create_folder.dart @@ -14,6 +14,12 @@ class _NewsCreateFolderDialogState extends State { final controller = TextEditingController(); + @override + void dispose() { + controller.dispose(); + super.dispose(); + } + void submit() { if (formKey.currentState!.validate()) { Navigator.of(context).pop(controller.text); diff --git a/packages/neon/neon_notes/lib/dialogs/create_note.dart b/packages/neon/neon_notes/lib/dialogs/create_note.dart index 0fb0d02c..fd3d8598 100644 --- a/packages/neon/neon_notes/lib/dialogs/create_note.dart +++ b/packages/neon/neon_notes/lib/dialogs/create_note.dart @@ -19,6 +19,12 @@ class _NotesCreateNoteDialogState extends State { final controller = TextEditingController(); String? selectedCategory; + @override + void dispose() { + controller.dispose(); + super.dispose(); + } + void submit() { if (formKey.currentState!.validate()) { Navigator.of(context).pop((controller.text, widget.category ?? selectedCategory)); diff --git a/packages/neon/neon_notes/lib/pages/note.dart b/packages/neon/neon_notes/lib/pages/note.dart index f5336f83..d49d4552 100644 --- a/packages/neon/neon_notes/lib/pages/note.dart +++ b/packages/neon/neon_notes/lib/pages/note.dart @@ -15,8 +15,8 @@ class NotesNotePage extends StatefulWidget { } class _NotesNotePageState extends State { - late final _contentController = TextEditingController()..text = widget.bloc.initialContent; - late final _titleController = TextEditingController()..text = widget.bloc.initialTitle; + final _contentController = TextEditingController(); + final _titleController = TextEditingController(); final _contentFocusNode = FocusNode(); final _titleFocusNode = FocusNode(); bool _showEditor = false; @@ -36,6 +36,9 @@ class _NotesNotePageState extends State { handleNotesException(context, error); }); + _contentController.text = widget.bloc.initialContent; + _titleController.text = widget.bloc.initialTitle; + _contentStreamController.stream.debounceTime(const Duration(seconds: 1)).listen(widget.bloc.updateContent); _titleStreamController.stream.debounceTime(const Duration(seconds: 1)).listen(widget.bloc.updateTitle); _contentController.addListener(() => _contentStreamController.add(_contentController.text)); @@ -56,6 +59,8 @@ class _NotesNotePageState extends State { @override void dispose() { + _contentController.dispose(); + _titleController.dispose(); unawaited(_contentStreamController.close()); unawaited(_titleStreamController.close()); super.dispose(); From 38873e52eb805b6556fb3d6f150e7ab4824a3cbe Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Tue, 5 Sep 2023 12:05:14 +0200 Subject: [PATCH 2/3] fix(neon,neon_notes): properly dispose FocusNodes Signed-off-by: Nikolas Rimikis --- packages/neon/neon/lib/src/widgets/app_bar.dart | 1 + packages/neon/neon_notes/lib/pages/note.dart | 2 ++ 2 files changed, 3 insertions(+) diff --git a/packages/neon/neon/lib/src/widgets/app_bar.dart b/packages/neon/neon/lib/src/widgets/app_bar.dart index 84abc267..66782d4a 100644 --- a/packages/neon/neon/lib/src/widgets/app_bar.dart +++ b/packages/neon/neon/lib/src/widgets/app_bar.dart @@ -55,6 +55,7 @@ class _NeonAppBarState extends State { @override void dispose() { + _searchBarFocusNode.dispose(); unawaited(_searchTermSubscription.cancel()); unawaited(_searchTermController.close()); super.dispose(); diff --git a/packages/neon/neon_notes/lib/pages/note.dart b/packages/neon/neon_notes/lib/pages/note.dart index d49d4552..96254f7a 100644 --- a/packages/neon/neon_notes/lib/pages/note.dart +++ b/packages/neon/neon_notes/lib/pages/note.dart @@ -61,6 +61,8 @@ class _NotesNotePageState extends State { void dispose() { _contentController.dispose(); _titleController.dispose(); + _contentFocusNode.dispose(); + _titleFocusNode.dispose(); unawaited(_contentStreamController.close()); unawaited(_titleStreamController.close()); super.dispose(); From f4289bbc0a750ee7e352f01392db27b6c4a83791 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Tue, 5 Sep 2023 12:05:14 +0200 Subject: [PATCH 3/3] fix(neon,neon_files): properly dispose blocs Signed-off-by: Nikolas Rimikis --- packages/neon/neon/lib/neon.dart | 10 ++++++++++ packages/neon/neon/lib/src/bloc/bloc.dart | 1 + packages/neon/neon/lib/src/blocs/apps.dart | 4 +--- .../neon/neon/lib/src/blocs/login_check_account.dart | 2 ++ .../neon/lib/src/blocs/login_check_server_status.dart | 2 ++ packages/neon/neon/lib/src/blocs/login_flow.dart | 2 ++ .../neon/neon/lib/src/models/app_implementation.dart | 5 ++--- packages/neon/neon_files/lib/blocs/files.dart | 2 ++ 8 files changed, 22 insertions(+), 6 deletions(-) diff --git a/packages/neon/neon/lib/neon.dart b/packages/neon/neon/lib/neon.dart index 62d4e126..2df80d53 100644 --- a/packages/neon/neon/lib/neon.dart +++ b/packages/neon/neon/lib/neon.dart @@ -67,21 +67,31 @@ Future runNeon({ providers: [ Provider( create: (final _) => globalOptions, + dispose: (final _, final globalOptions) => globalOptions.dispose(), ), Provider( create: (final _) => accountsBloc, + dispose: (final _, final accountsBloc) => accountsBloc.dispose(), ), Provider( create: (final _) => pushNotificationsBloc, + dispose: (final _, final pushNotificationsBloc) => pushNotificationsBloc.dispose(), ), Provider( create: (final _) => firstLaunchBloc, + dispose: (final _, final firstLaunchBloc) => firstLaunchBloc.dispose(), ), Provider( create: (final _) => nextPushBloc, + dispose: (final _, final nextPushBloc) => nextPushBloc.dispose(), ), Provider>( create: (final _) => appImplementations, + dispose: (final _, final appImplementations) { + for (final app in appImplementations) { + app.dispose(); + } + }, ), Provider( create: (final _) => packageInfo, diff --git a/packages/neon/neon/lib/src/bloc/bloc.dart b/packages/neon/neon/lib/src/bloc/bloc.dart index d1e9b2bf..96263e4c 100644 --- a/packages/neon/neon/lib/src/bloc/bloc.dart +++ b/packages/neon/neon/lib/src/bloc/bloc.dart @@ -4,6 +4,7 @@ import 'package:flutter/foundation.dart'; import 'package:neon/src/utils/request_manager.dart'; abstract class Bloc { + @mustCallSuper void dispose(); } diff --git a/packages/neon/neon/lib/src/blocs/apps.dart b/packages/neon/neon/lib/src/blocs/apps.dart index 6f35a3ec..5b40c9b2 100644 --- a/packages/neon/neon/lib/src/blocs/apps.dart +++ b/packages/neon/neon/lib/src/blocs/apps.dart @@ -164,9 +164,7 @@ class AppsBloc extends InteractiveBloc implements AppsBlocEvents, AppsBlocStates unawaited(openNotifications.close()); unawaited(appVersions.close()); - for (final app in _allAppImplementations) { - app.dispose(); - } + super.dispose(); } @override diff --git a/packages/neon/neon/lib/src/blocs/login_check_account.dart b/packages/neon/neon/lib/src/blocs/login_check_account.dart index 380ef064..f7b97561 100644 --- a/packages/neon/neon/lib/src/blocs/login_check_account.dart +++ b/packages/neon/neon/lib/src/blocs/login_check_account.dart @@ -32,6 +32,8 @@ class LoginCheckAccountBloc extends InteractiveBloc @override void dispose() { unawaited(state.close()); + + super.dispose(); } @override diff --git a/packages/neon/neon/lib/src/blocs/login_check_server_status.dart b/packages/neon/neon/lib/src/blocs/login_check_server_status.dart index 65b8526e..a92529f1 100644 --- a/packages/neon/neon/lib/src/blocs/login_check_server_status.dart +++ b/packages/neon/neon/lib/src/blocs/login_check_server_status.dart @@ -25,6 +25,8 @@ class LoginCheckServerStatusBloc extends InteractiveBloc @override void dispose() { unawaited(state.close()); + + super.dispose(); } @override diff --git a/packages/neon/neon/lib/src/blocs/login_flow.dart b/packages/neon/neon/lib/src/blocs/login_flow.dart index 3a25c087..ee6cfc10 100644 --- a/packages/neon/neon/lib/src/blocs/login_flow.dart +++ b/packages/neon/neon/lib/src/blocs/login_flow.dart @@ -34,6 +34,8 @@ class LoginFlowBloc extends InteractiveBloc implements LoginFlowBlocEvents, Logi _cancelPollTimer(); unawaited(init.close()); unawaited(_resultController.close()); + + super.dispose(); } @override diff --git a/packages/neon/neon/lib/src/models/app_implementation.dart b/packages/neon/neon/lib/src/models/app_implementation.dart index b8f184ed..5051d0e6 100644 --- a/packages/neon/neon/lib/src/models/app_implementation.dart +++ b/packages/neon/neon/lib/src/models/app_implementation.dart @@ -105,11 +105,10 @@ abstract class AppImplementation ), ); + @mustCallSuper void dispose() { options.dispose(); - for (final bloc in _blocs.values) { - bloc.dispose(); - } + _blocs.disposeAll(); } /// A custom theme that will be injected into the widget tree. diff --git a/packages/neon/neon_files/lib/blocs/files.dart b/packages/neon/neon_files/lib/blocs/files.dart index 608b82ec..855f1b0c 100644 --- a/packages/neon/neon_files/lib/blocs/files.dart +++ b/packages/neon/neon_files/lib/blocs/files.dart @@ -48,6 +48,8 @@ class FilesBloc extends InteractiveBloc implements FilesBlocEvents, FilesBlocSta options.uploadQueueParallelism.removeListener(_uploadParallelismListener); options.downloadQueueParallelism.removeListener(_downloadParallelismListener); + + super.dispose(); } @override