From cf06c674030d13077a35049608b8ffa15b35368a Mon Sep 17 00:00:00 2001 From: Bent Hillerkus <29630575+benthillerkus@users.noreply.github.com> Date: Sat, 22 Mar 2025 00:53:32 +0100 Subject: [PATCH 1/2] feat: add Hook for managing SnapshotController instances --- packages/flutter_hooks/lib/src/hooks.dart | 1 + .../lib/src/snapshot_controller.dart | 61 +++++++++++++++ .../test/use_snapshot_controller_test.dart | 75 +++++++++++++++++++ 3 files changed, 137 insertions(+) create mode 100644 packages/flutter_hooks/lib/src/snapshot_controller.dart create mode 100644 packages/flutter_hooks/test/use_snapshot_controller_test.dart diff --git a/packages/flutter_hooks/lib/src/hooks.dart b/packages/flutter_hooks/lib/src/hooks.dart index d1e4664..b5e1d56 100644 --- a/packages/flutter_hooks/lib/src/hooks.dart +++ b/packages/flutter_hooks/lib/src/hooks.dart @@ -41,3 +41,4 @@ part 'transformation_controller.dart'; part 'tree_sliver_controller.dart'; part 'widget_states_controller.dart'; part 'widgets_binding_observer.dart'; +part 'snapshot_controller.dart'; \ No newline at end of file diff --git a/packages/flutter_hooks/lib/src/snapshot_controller.dart b/packages/flutter_hooks/lib/src/snapshot_controller.dart new file mode 100644 index 0000000..9fcf70a --- /dev/null +++ b/packages/flutter_hooks/lib/src/snapshot_controller.dart @@ -0,0 +1,61 @@ +part of 'hooks.dart'; + +/// Creates and disposes a [SnapshotController]. +/// +/// Note that [allowSnapshotting] must be set to `true` +/// in order for this controller to actually do anything. +/// This is consistent with [SnapshotController.new]. +/// +/// If [allowSnapshotting] changes on subsequent calls to [useSnapshotController], +/// [SnapshotController.allowSnapshotting] will be called to update accordingly. +/// +/// ```dart +/// final controller = useSnapshotController(allowSnapshotting: true); +/// // is equivalent to +/// final controller = useSnapshotController(); +/// controller.allowSnapshotting = true; +/// ``` +/// +/// See also: +/// - [SnapshotController] +SnapshotController useSnapshotController({ + bool allowSnapshotting = false, +}) { + return use( + _SnapshotControllerHook( + allowSnapshotting: allowSnapshotting, + ), + ); +} + +class _SnapshotControllerHook extends Hook { + const _SnapshotControllerHook({ + required this.allowSnapshotting, + }); + + final bool allowSnapshotting; + + @override + HookState> + createState() => _SnapshotControllerHookState(); +} + +class _SnapshotControllerHookState + extends HookState { + late final controller = SnapshotController(allowSnapshotting: hook.allowSnapshotting); + + @override + void didUpdateHook(_SnapshotControllerHook oldHook) { + super.didUpdateHook(oldHook); + controller.allowSnapshotting = hook.allowSnapshotting; + } + + @override + SnapshotController build(BuildContext context) => controller; + + @override + void dispose() => controller.dispose(); + + @override + String get debugLabel => 'useSnapshotController'; +} diff --git a/packages/flutter_hooks/test/use_snapshot_controller_test.dart b/packages/flutter_hooks/test/use_snapshot_controller_test.dart new file mode 100644 index 0000000..842691d --- /dev/null +++ b/packages/flutter_hooks/test/use_snapshot_controller_test.dart @@ -0,0 +1,75 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_hooks/src/framework.dart'; +import 'package:flutter_hooks/src/hooks.dart'; + +import 'mock.dart'; + +void main() { + testWidgets('debugFillProperties', (tester) async { + await tester.pumpWidget( + HookBuilder(builder: (context) { + useSnapshotController(); + return const SizedBox(); + }), + ); + + await tester.pump(); + + final element = tester.element(find.byType(HookBuilder)); + + expect( + element + .toDiagnosticsNode(style: DiagnosticsTreeStyle.offstage) + .toStringDeep(), + equalsIgnoringHashCodes( + 'HookBuilder\n' + " │ useSnapshotController: Instance of 'SnapshotController'\n" + ' └SizedBox(renderObject: RenderConstrainedBox#00000)\n', + ), + ); + }); + + group('useSnapshotController', () { + testWidgets('initial values matches with real constructor', (tester) async { + late SnapshotController controller; + late SnapshotController controller2; + + await tester.pumpWidget( + HookBuilder(builder: (context) { + controller2 = SnapshotController(); + controller = useSnapshotController(); + return Container(); + }), + ); + + expect(controller.allowSnapshotting, controller2.allowSnapshotting); + }); + + testWidgets('passes hook parameters to the SnapshotController', + (tester) async { + late SnapshotController controller; + + await tester.pumpWidget( + HookBuilder(builder: (context) { + controller = useSnapshotController(allowSnapshotting: true); + return const SizedBox(); + }), + ); + + expect(controller.allowSnapshotting, true); + + late SnapshotController retrievedController; + await tester.pumpWidget( + HookBuilder(builder: (context) { + // ignore: avoid_redundant_argument_values + retrievedController = useSnapshotController(allowSnapshotting: false); + return const SizedBox(); + }), + ); + + expect(retrievedController, same(controller)); + expect(retrievedController.allowSnapshotting, false); + }); + }); +} From 846bc3a69982a84bad7a26f0ea11f3792868b919 Mon Sep 17 00:00:00 2001 From: Bent Hillerkus <29630575+benthillerkus@users.noreply.github.com> Date: Sat, 22 Mar 2025 01:16:13 +0100 Subject: [PATCH 2/2] chore: autoformat --- packages/flutter_hooks/lib/src/hooks.dart | 2 +- .../flutter_hooks/lib/src/snapshot_controller.dart | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/flutter_hooks/lib/src/hooks.dart b/packages/flutter_hooks/lib/src/hooks.dart index b5e1d56..2ad681b 100644 --- a/packages/flutter_hooks/lib/src/hooks.dart +++ b/packages/flutter_hooks/lib/src/hooks.dart @@ -41,4 +41,4 @@ part 'transformation_controller.dart'; part 'tree_sliver_controller.dart'; part 'widget_states_controller.dart'; part 'widgets_binding_observer.dart'; -part 'snapshot_controller.dart'; \ No newline at end of file +part 'snapshot_controller.dart'; diff --git a/packages/flutter_hooks/lib/src/snapshot_controller.dart b/packages/flutter_hooks/lib/src/snapshot_controller.dart index 9fcf70a..d5b69ec 100644 --- a/packages/flutter_hooks/lib/src/snapshot_controller.dart +++ b/packages/flutter_hooks/lib/src/snapshot_controller.dart @@ -1,14 +1,14 @@ part of 'hooks.dart'; /// Creates and disposes a [SnapshotController]. -/// +/// /// Note that [allowSnapshotting] must be set to `true` /// in order for this controller to actually do anything. /// This is consistent with [SnapshotController.new]. -/// +/// /// If [allowSnapshotting] changes on subsequent calls to [useSnapshotController], /// [SnapshotController.allowSnapshotting] will be called to update accordingly. -/// +/// /// ```dart /// final controller = useSnapshotController(allowSnapshotting: true); /// // is equivalent to @@ -36,13 +36,14 @@ class _SnapshotControllerHook extends Hook { final bool allowSnapshotting; @override - HookState> - createState() => _SnapshotControllerHookState(); + HookState> createState() => + _SnapshotControllerHookState(); } class _SnapshotControllerHookState extends HookState { - late final controller = SnapshotController(allowSnapshotting: hook.allowSnapshotting); + late final controller = + SnapshotController(allowSnapshotting: hook.allowSnapshotting); @override void didUpdateHook(_SnapshotControllerHook oldHook) {