From 129d6c5c4e678c7344513f67974c0721d193ebb0 Mon Sep 17 00:00:00 2001 From: Fedor Blagodyr Date: Wed, 6 Aug 2025 17:29:57 +0300 Subject: [PATCH 1/4] fix: incorrect overlay box keys usage --- CHANGELOG.md | 4 + example/pubspec.lock | 84 +++++++++---------- lib/src/core/easy_dialogs_controller.dart | 26 ++++-- lib/src/core/easy_overlay.dart | 58 ++++++++++--- lib/src/core/widget/overlay_provider.dart | 5 +- .../dialog/full_screen_dialog.dart | 46 +--------- .../positioned/dialog/positioned_dialog.dart | 65 +------------- pubspec.yaml | 2 +- .../dialog/full_screen_dialog_test.dart | 6 +- test/src/full_screen/dialog/insert_test.dart | 21 +++-- test/src/positioned/dialog/insert_test.dart | 73 +++++++--------- 11 files changed, 162 insertions(+), 228 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c1bd86..ab5db23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 4.0.4 +* **FIX:** Fixed https://github.com/feduke-nukem/flutter_easy_dialogs/issues/37 +* **FIX:** Fixed https://github.com/feduke-nukem/flutter_easy_dialogs/issues/38 + ## 4.0.3 * **FIX:** Adds necessary fields to clone methods. diff --git a/example/pubspec.lock b/example/pubspec.lock index c415a24..3cd213b 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -5,50 +5,50 @@ packages: dependency: transitive description: name: async - sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" url: "https://pub.dev" source: hosted - version: "2.11.0" + version: "2.13.0" boolean_selector: dependency: transitive description: name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" characters: dependency: transitive description: name: characters - sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.4.0" clock: dependency: transitive description: name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" collection: dependency: transitive description: name: collection - sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" url: "https://pub.dev" source: hosted - version: "1.19.0" + version: "1.19.1" fake_async: dependency: transitive description: name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.3" flutter: dependency: "direct main" description: flutter @@ -68,7 +68,7 @@ packages: path: ".." relative: true source: path - version: "4.0.2" + version: "4.0.4" flutter_lints: dependency: "direct dev" description: @@ -86,26 +86,26 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06" + sha256: "8dcda04c3fc16c14f48a7bb586d4be1f0d1572731b6d81d51772ef47c02081e0" url: "https://pub.dev" source: hosted - version: "10.0.7" + version: "11.0.1" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379" + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" url: "https://pub.dev" source: hosted - version: "3.0.8" + version: "3.0.10" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" lints: dependency: transitive description: @@ -118,10 +118,10 @@ packages: dependency: transitive description: name: matcher - sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 url: "https://pub.dev" source: hosted - version: "0.12.16+1" + version: "0.12.17" material_color_utilities: dependency: transitive description: @@ -134,18 +134,18 @@ packages: dependency: transitive description: name: meta - sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 + sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c url: "https://pub.dev" source: hosted - version: "1.15.0" + version: "1.16.0" path: dependency: transitive description: name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.9.1" sky_engine: dependency: transitive description: flutter @@ -155,66 +155,66 @@ packages: dependency: transitive description: name: source_span - sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.10.1" stack_trace: dependency: transitive description: name: stack_trace - sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" url: "https://pub.dev" source: hosted - version: "1.12.0" + version: "1.12.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.4" string_scanner: dependency: transitive description: name: string_scanner - sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" + sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.4.1" term_glyph: dependency: transitive description: name: term_glyph - sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.2.2" test_api: dependency: transitive description: name: test_api - sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" + sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" url: "https://pub.dev" source: hosted - version: "0.7.3" + version: "0.7.6" vector_math: dependency: transitive description: name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.0" vm_service: dependency: transitive description: name: vm_service - sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b + sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02 url: "https://pub.dev" source: hosted - version: "14.3.0" + version: "15.0.0" sdks: - dart: ">=3.4.0 <4.0.0" + dart: ">=3.7.0-0 <4.0.0" flutter: ">=3.18.0-18.0.pre.54" diff --git a/lib/src/core/easy_dialogs_controller.dart b/lib/src/core/easy_dialogs_controller.dart index d76ed38..e79ba0b 100644 --- a/lib/src/core/easy_dialogs_controller.dart +++ b/lib/src/core/easy_dialogs_controller.dart @@ -6,7 +6,6 @@ import 'dart:math' as math; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; - import 'package:flutter_easy_dialogs/flutter_easy_dialogs.dart'; import 'package:flutter_easy_dialogs/src/core/widget/free_positioned.dart'; @@ -93,8 +92,10 @@ final class EasyDialogsController { bool Function(D dialog) test, { bool instantly = false, }) { + final entries = this.entries.values.toList(); + return Future.wait( - entries.values.where( + entries.where( (entry) { final dialog = entry.dialog; @@ -181,12 +182,18 @@ final class EasyDialogsController { Object? result, }) async { final effectiveId = id is EasyDialog ? id.id : id; - assert( - entries[effectiveId] != null, - 'dialog is not registered in this conversation', - ); - final entry = entries[effectiveId]!; + final entry = entries[effectiveId]; + + if (entry == null) { + assert( + false, + 'dialog is not shown or was hidden with id: $effectiveId', + ); + + return; + } + entry.dialog._pendingResult = result; final needReverseAnimation = switch (entry.dialog.animationConfiguration) { @@ -369,12 +376,13 @@ abstract base class EasyDialog with EasyDialogLifecycle { /// @nodoc @factory @protected - EasyOverlayBoxInsertion createInsert(Widget decorated); + EasyOverlayBoxInsertion createInsert(Widget decorated) => + DefaultEasyOverlayBoxInsertion(id: id, dialog: decorated); /// @nodoc @factory @protected - EasyOverlayBoxRemoval createRemove(); + EasyOverlayBoxRemoval createRemove() => DefaultEasyOverlayBoxRemoval(id: id); EasyDialog _copyWith({ Widget? content, diff --git a/lib/src/core/easy_overlay.dart b/lib/src/core/easy_overlay.dart index 2882b24..9e60cee 100644 --- a/lib/src/core/easy_overlay.dart +++ b/lib/src/core/easy_overlay.dart @@ -40,6 +40,8 @@ final class EasyDialogsOverlayBox { void put(Object key, Object value) => currentEntries[key] = value; T? remove(Object key) => currentEntries.remove(key) as T?; + + bool containsKey(Object key) => currentEntries.containsKey(key); } /// {@category Overlay} @@ -49,19 +51,11 @@ final class EasyDialogsOverlayBox { /// It is intended to be used as a base class for /// creating custom mutation operations. /// -/// This class has two generic type parameters: -/// -/// [D] represents the type of [EasyDialog] that this mutation -/// associates to with the [dialogType] getter. -/// /// [R] represents the type of the return value for the [call] method, /// it should extends [EasyOverlayEntry] which can bu nullable. -abstract interface class EasyOverlayBoxMutation { +abstract interface class EasyOverlayBoxMutation { const EasyOverlayBoxMutation(); - Type get dialogType => D; - /// Apply mutation to provided [box]. /// /// The result is [R]. @@ -71,8 +65,8 @@ abstract interface class EasyOverlayBoxMutation - extends EasyOverlayBoxMutation { +abstract base class EasyOverlayBoxInsertion + extends EasyOverlayBoxMutation { final Widget dialog; /// @nodoc @@ -82,8 +76,8 @@ abstract base class EasyOverlayBoxInsertion /// {@category Overlay} /// {@category Custom} /// Removal mutation. -abstract base class EasyOverlayBoxRemoval - extends EasyOverlayBoxMutation { +abstract base class EasyOverlayBoxRemoval + extends EasyOverlayBoxMutation { const EasyOverlayBoxRemoval(); } @@ -128,3 +122,41 @@ base class EasyDialogsOverlayEntry extends EasyOverlayEntry { /// Creates an instance of [EasyDialogsOverlayEntry]. EasyDialogsOverlayEntry({required super.builder}); } + +/// {@category Overlay} +/// Default insertion for the [EasyDialogsOverlayBox] based on [id]. +final class DefaultEasyOverlayBoxInsertion extends EasyOverlayBoxInsertion { + final Object id; + const DefaultEasyOverlayBoxInsertion({ + required this.id, + required super.dialog, + }); + + @override + EasyOverlayEntry call(EasyDialogsOverlayBox box) { + assert( + !box.containsKey(id), + 'only single one $EasyDialogsOverlayEntry with the same $id can be inserted at the same time', + ); + + final entry = EasyDialogsOverlayEntry( + builder: (_) => dialog, + ); + + box.put(id, entry); + + return entry; + } +} + +/// {@category Overlay} +/// Default removal for the [EasyDialogsOverlayBox] based on [id]. +final class DefaultEasyOverlayBoxRemoval extends EasyOverlayBoxRemoval { + final Object id; + + const DefaultEasyOverlayBoxRemoval({required this.id}); + + @override + EasyOverlayEntry? call(EasyDialogsOverlayBox box) => + box.remove(id); +} diff --git a/lib/src/core/widget/overlay_provider.dart b/lib/src/core/widget/overlay_provider.dart index 8687af1..72261e0 100644 --- a/lib/src/core/widget/overlay_provider.dart +++ b/lib/src/core/widget/overlay_provider.dart @@ -46,10 +46,9 @@ class OverlayProviderState extends State _overlayKey.currentState!.createTicker(onTick); @override - void insertDialog(EasyOverlayBoxInsertion insertion) => + void insertDialog(EasyOverlayBoxInsertion insertion) => _overlayKey.currentState!.insert(insertion(box)); @override - void removeDialog(EasyOverlayBoxRemoval removal) => - (removal(box))?.remove(); + void removeDialog(EasyOverlayBoxRemoval removal) => (removal(box))?.remove(); } diff --git a/lib/src/full_screen/dialog/full_screen_dialog.dart b/lib/src/full_screen/dialog/full_screen_dialog.dart index 951e6ef..500392b 100644 --- a/lib/src/full_screen/dialog/full_screen_dialog.dart +++ b/lib/src/full_screen/dialog/full_screen_dialog.dart @@ -1,8 +1,7 @@ import 'dart:async'; -import 'package:flutter/material.dart'; -import 'package:flutter_easy_dialogs/src/core/core.dart'; import 'package:flutter_easy_dialogs/src/core/android_back_button_interceptor_mixin.dart'; +import 'package:flutter_easy_dialogs/src/core/core.dart'; typedef FullScreenWillPopCallback = FutureOr Function(); @@ -30,13 +29,6 @@ final class FullScreenDialog extends EasyDialog super.autoHideDuration, }); - @override - EasyOverlayBoxInsertion createInsert(Widget decorated) => - FullScreenDialogInsert(dialog: decorated); - - @override - EasyOverlayBoxRemoval createRemove() => const FullScreenDialogRemove(); - @override Future onAndroidPop() async { if (androidWillPop == null) return; @@ -57,45 +49,11 @@ final class FullScreenDialog extends EasyDialog EasyDialog clone() { return FullScreenDialog( content: content, + id: id, androidWillPop: androidWillPop, animationConfiguration: animationConfiguration, decoration: decoration, autoHideDuration: autoHideDuration, - id: id, - ); - } -} - -@visibleForTesting -final class FullScreenDialogInsert - extends EasyOverlayBoxInsertion { - /// @nodoc - const FullScreenDialogInsert({required super.dialog}); - - @override - EasyOverlayEntry call(EasyDialogsOverlayBox box) { - assert( - box.get(super.dialogType) == null, - 'only single one full screen $EasyDialogsOverlayEntry can be presented', ); - - final entry = EasyDialogsOverlayEntry( - builder: (_) => dialog, - ); - - box.put(super.dialogType, entry); - - return entry; } } - -@visibleForTesting -final class FullScreenDialogRemove - extends EasyOverlayBoxRemoval { - /// Creates a new instance of the [FullScreenDialogRemove]. - const FullScreenDialogRemove(); - - @override - EasyOverlayEntry? call(EasyDialogsOverlayBox box) => - box.remove(dialogType); -} diff --git a/lib/src/positioned/dialog/positioned_dialog.dart b/lib/src/positioned/dialog/positioned_dialog.dart index 9de4169..ff4414b 100644 --- a/lib/src/positioned/dialog/positioned_dialog.dart +++ b/lib/src/positioned/dialog/positioned_dialog.dart @@ -26,20 +26,15 @@ final class PositionedDialog extends EasyDialog { }) : super(id: id ?? position); @override - EasyOverlayBoxInsertion createInsert(Widget decorated) { - return PositionedDialogInsert( - position: position, - dialog: Align( + EasyOverlayBoxInsertion createInsert(Widget decorated) { + return super.createInsert( + Align( alignment: position.alignment, child: decorated, ), ); } - @override - EasyOverlayBoxRemoval createRemove() => - PositionedDialogRemove(position: position); - @override EasyDialog clone() { return PositionedDialog( @@ -63,57 +58,3 @@ enum EasyDialogPosition { const EasyDialogPosition(this.alignment); } - -@visibleForTesting -final class PositionedDialogInsert - extends EasyOverlayBoxInsertion { - final EasyDialogPosition position; - - const PositionedDialogInsert({ - required this.position, - required super.dialog, - }); - - @override - EasyOverlayEntry call(EasyDialogsOverlayBox box) { - final container = - box.putIfAbsent>( - dialogType, - () => {}, - ); - assert( - !container.containsKey(position), - 'only single one $EasyDialogsOverlayEntry with the same $EasyDialogPosition can be presented at the same time', - ); - - final entry = EasyDialogsOverlayEntry( - builder: (_) => dialog, - ); - - container[position] = entry; - - return entry; - } -} - -@visibleForTesting -final class PositionedDialogRemove - extends EasyOverlayBoxRemoval { - final EasyDialogPosition position; - - const PositionedDialogRemove({ - required this.position, - }); - - @override - EasyOverlayEntry? call(EasyDialogsOverlayBox box) { - final container = - box.get>(dialogType); - - assert(container != null, 'entries container is not initialized'); - - if (container!.entries.isEmpty) return null; - - return container.remove(position); - } -} diff --git a/pubspec.yaml b/pubspec.yaml index 0419001..c6e8140 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_easy_dialogs description: Easy and flexible package for showing dialogs inside your Flutter application without BuildContext. -version: 4.0.3 +version: 4.0.4 homepage: https://github.com/feduke-nukem/flutter_easy_dialogs repository: https://github.com/feduke-nukem/flutter_easy_dialogs/tree/main issue_tracker: https://github.com/feduke-nukem/flutter_easy_dialogs/issues diff --git a/test/src/full_screen/dialog/full_screen_dialog_test.dart b/test/src/full_screen/dialog/full_screen_dialog_test.dart index c0a26c0..56913ea 100644 --- a/test/src/full_screen/dialog/full_screen_dialog_test.dart +++ b/test/src/full_screen/dialog/full_screen_dialog_test.dart @@ -31,7 +31,7 @@ void main() { expect(easyOverlayState.box.currentEntries.isNotEmpty, isTrue); expect( - easyOverlayState.box.get(FullScreenDialog), + easyOverlayState.box.get(FullScreenDialog.defaultId), isA(), ); @@ -42,7 +42,7 @@ void main() { expect(find.byKey(dialogKey), findsNothing); expect(easyOverlayState.box.currentEntries.isEmpty, isTrue); - expect(easyOverlayState.box.get(FullScreenDialog), isNull); + expect(easyOverlayState.box.get(FullScreenDialog.defaultId), isNull); }); testWidgets('show one, then show another', (widgetTester) async { @@ -70,7 +70,7 @@ void main() { expect(find.byKey(const Key('value')), findsOneWidget); expect(easyOverlayState.box.currentEntries.isNotEmpty, isTrue); - expect(easyOverlayState.box.get(FullScreenDialog), isNotNull); + expect(easyOverlayState.box.get(FullScreenDialog.defaultId), isNotNull); }); }); diff --git a/test/src/full_screen/dialog/insert_test.dart b/test/src/full_screen/dialog/insert_test.dart index fbe7c7a..c21ebf3 100644 --- a/test/src/full_screen/dialog/insert_test.dart +++ b/test/src/full_screen/dialog/insert_test.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_easy_dialogs/src/core/easy_overlay.dart'; import 'package:flutter_easy_dialogs/src/full_screen/dialog/full_screen_dialog.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -15,7 +16,8 @@ void main() { ); easyOverlayState.insertDialog( - const FullScreenDialogInsert( + const DefaultEasyOverlayBoxInsertion( + id: FullScreenDialog.defaultId, dialog: SizedBox.shrink( key: dialogKey, ), @@ -23,7 +25,7 @@ void main() { ); expect( - easyOverlayState.box.currentEntries[FullScreenDialog], + easyOverlayState.box.currentEntries[FullScreenDialog.defaultId], isNotNull, ); @@ -39,7 +41,8 @@ void main() { await widgetTester.pumpWidget(app()); easyOverlayState.insertDialog( - const FullScreenDialogInsert( + const DefaultEasyOverlayBoxInsertion( + id: FullScreenDialog.defaultId, dialog: SizedBox.shrink( key: dialogKey, ), @@ -48,7 +51,8 @@ void main() { expect( () => easyOverlayState.insertDialog( - const FullScreenDialogInsert( + const DefaultEasyOverlayBoxInsertion( + id: FullScreenDialog.defaultId, dialog: SizedBox.shrink( key: dialogKey, ), @@ -69,13 +73,18 @@ void main() { easyOverlayState ..insertDialog( - const FullScreenDialogInsert( + const DefaultEasyOverlayBoxInsertion( + id: FullScreenDialog.defaultId, dialog: SizedBox.shrink( key: dialogKey, ), ), ) - ..removeDialog(const FullScreenDialogRemove()); + ..removeDialog( + const DefaultEasyOverlayBoxRemoval( + id: FullScreenDialog.defaultId, + ), + ); expect( easyOverlayState.box.currentEntries[FullScreenDialog], diff --git a/test/src/positioned/dialog/insert_test.dart b/test/src/positioned/dialog/insert_test.dart index f9fdadc..8d24faf 100644 --- a/test/src/positioned/dialog/insert_test.dart +++ b/test/src/positioned/dialog/insert_test.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:flutter_easy_dialogs/flutter_easy_dialogs.dart'; -import 'package:flutter_easy_dialogs/src/positioned/dialog/positioned_dialog.dart'; import 'package:flutter_test/flutter_test.dart'; import '../../../helper.dart'; @@ -13,8 +12,8 @@ void main() { ); const position = EasyDialogPosition.top; - const strategy = PositionedDialogInsert( - position: position, + const strategy = DefaultEasyOverlayBoxInsertion( + id: position, dialog: SizedBox.shrink( key: dialogKey, ), @@ -22,23 +21,14 @@ void main() { easyOverlayState.insertDialog(strategy); - var entries = easyOverlayState.box.currentEntries[PositionedDialog]; + final dialogEntry = easyOverlayState.box.currentEntries[position]; expect( - entries, + dialogEntry, isNotNull, ); - expect( - entries, - isNotNull, - ); - - expect(entries!, isA>()); - - entries = entries as Map; - - expect(entries.length, greaterThan(0)); + expect(dialogEntry!, isA()); await widgetTester.pump(); @@ -46,11 +36,11 @@ void main() { }); testWidgets( - 'insert the same position', + 'insert the same id - throws assertion error', (widgetTester) async { await widgetTester.pumpWidget(app()); - const strategy = PositionedDialogInsert( - position: EasyDialogPosition.bottom, + const strategy = DefaultEasyOverlayBoxInsertion( + id: EasyDialogPosition.bottom, dialog: SizedBox.shrink(), ); @@ -69,8 +59,8 @@ void main() { await widgetTester.pumpWidget(app()); final strategies = EasyDialogPosition.values.map( - (e) => PositionedDialogInsert( - position: e, + (e) => DefaultEasyOverlayBoxInsertion( + id: e, dialog: SizedBox.shrink( key: ValueKey(e), ), @@ -82,9 +72,7 @@ void main() { } expect( - easyOverlayState.box - .get>(PositionedDialog)! - .length, + easyOverlayState.box.currentEntries.length, EasyDialogPosition.values.length, ); @@ -103,11 +91,11 @@ void main() { expect( () => easyOverlayState.removeDialog( - const PositionedDialogRemove( - position: EasyDialogPosition.bottom, + const DefaultEasyOverlayBoxRemoval( + id: EasyDialogPosition.bottom, ), ), - throwsAssertionError, + returnsNormally, ); }); testWidgets('insert one and remove one', (widgetTester) async { @@ -115,8 +103,8 @@ void main() { const position = EasyDialogPosition.bottom; easyOverlayState.insertDialog( - const PositionedDialogInsert( - position: position, + const DefaultEasyOverlayBoxInsertion( + id: position, dialog: SizedBox.shrink( key: dialogKey, ), @@ -128,20 +116,18 @@ void main() { expect(find.byKey(dialogKey), findsOneWidget); easyOverlayState.removeDialog( - const PositionedDialogRemove( - position: position, + const DefaultEasyOverlayBoxRemoval( + id: position, ), ); expect( - easyOverlayState.box.currentEntries[PositionedDialog], - isNotNull, + easyOverlayState.box.currentEntries[position], + isNull, ); expect( - easyOverlayState.box - .get>(PositionedDialog)! - .length, + easyOverlayState.box.currentEntries.length, isZero, ); @@ -156,12 +142,15 @@ void main() { await widgetTester.pumpWidget(app()); final insertStrategies = EasyDialogPosition.values.map( - (e) => PositionedDialogInsert(position: e, dialog: Container()), + (e) => DefaultEasyOverlayBoxInsertion( + id: e, + dialog: Container(), + ), ); final removeStrategies = EasyDialogPosition.values.map( - (e) => PositionedDialogRemove( - position: e, + (e) => DefaultEasyOverlayBoxRemoval( + id: e, ), ); @@ -185,15 +174,9 @@ void main() { find.byType(Container), findsNothing, ); - expect( - easyOverlayState.box.currentEntries[PositionedDialog], - isNotNull, - ); expect( - easyOverlayState.box - .get>(PositionedDialog)! - .length, + easyOverlayState.box.currentEntries.length, isZero, ); }, From bd75c277313517c6ceca06d1da1fed29a94be4f1 Mon Sep 17 00:00:00 2001 From: Fedor Blagodyr <72284940+feduke-nukem@users.noreply.github.com> Date: Wed, 6 Aug 2025 17:41:20 +0300 Subject: [PATCH 2/4] Update test/src/full_screen/dialog/insert_test.dart Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- test/src/full_screen/dialog/insert_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/src/full_screen/dialog/insert_test.dart b/test/src/full_screen/dialog/insert_test.dart index c21ebf3..af68231 100644 --- a/test/src/full_screen/dialog/insert_test.dart +++ b/test/src/full_screen/dialog/insert_test.dart @@ -87,7 +87,7 @@ void main() { ); expect( - easyOverlayState.box.currentEntries[FullScreenDialog], + easyOverlayState.box.currentEntries[FullScreenDialog.defaultId], isNull, ); From aa3dd092b8d6136d07bb120be7c5dc6c930dc008 Mon Sep 17 00:00:00 2001 From: Fedor Blagodyr Date: Wed, 6 Aug 2025 17:46:05 +0300 Subject: [PATCH 3/4] chore: lint fixes --- example/analysis_options.yaml | 1 - lib/src/full_screen/full_screen.dart | 3 +-- lib/src/positioned/positioned.dart | 3 +-- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/example/analysis_options.yaml b/example/analysis_options.yaml index 93edbae..3497dc3 100644 --- a/example/analysis_options.yaml +++ b/example/analysis_options.yaml @@ -38,7 +38,6 @@ linter: - omit_local_variable_types - only_throw_errors - overridden_fields - - package_api_docs - package_names - package_prefixed_library_names - prefer_adjacent_string_concatenation diff --git a/lib/src/full_screen/full_screen.dart b/lib/src/full_screen/full_screen.dart index 055a176..8aec968 100644 --- a/lib/src/full_screen/full_screen.dart +++ b/lib/src/full_screen/full_screen.dart @@ -1,4 +1,3 @@ +export 'dialog/full_screen_dialog.dart'; export 'shell/full_screen_shell.dart'; export 'widgets/widget.dart'; -export 'dialog/full_screen_dialog.dart' - hide FullScreenDialogInsert, FullScreenDialogRemove; diff --git a/lib/src/positioned/positioned.dart b/lib/src/positioned/positioned.dart index 79ba905..346a0eb 100644 --- a/lib/src/positioned/positioned.dart +++ b/lib/src/positioned/positioned.dart @@ -1,3 +1,2 @@ +export 'dialog/positioned_dialog.dart'; export 'shell/positioned_shell.dart'; -export 'dialog/positioned_dialog.dart' - hide PositionedDialogInsert, PositionedDialogRemove; From ed73298674f2b6ab7c84b86ba989287f0fb54203 Mon Sep 17 00:00:00 2001 From: Fedor Blagodyr Date: Wed, 6 Aug 2025 18:01:24 +0300 Subject: [PATCH 4/4] chore: added tests --- test/src/core/easy_dialog_controller_test.dart | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/src/core/easy_dialog_controller_test.dart b/test/src/core/easy_dialog_controller_test.dart index 472e830..e48eb66 100644 --- a/test/src/core/easy_dialog_controller_test.dart +++ b/test/src/core/easy_dialog_controller_test.dart @@ -136,6 +136,11 @@ void main() { content: Container(), autoHideDuration: null, ); + + expect(() => controller.hide(id: topDialog.id), throwsAssertionError); + expect(controller.isShown(id: topDialog.id), isFalse); + expect(() => controller.get(topDialog.id), throwsA(isA())); + controller.show(topDialog); final bottomDialog = EasyDialog.positioned( content: Container(), @@ -152,6 +157,9 @@ void main() { controller.show(centerDialog); await widgetTester.pumpAndSettle(const Duration(seconds: 3)); + expect(controller.isShown(id: topDialog.id), isTrue); + expect(() => controller.get(topDialog.id), returnsNormally); + controller.hideWhere( (element) => element.position == EasyDialogPosition.bottom ||