From f06b9c90dad101e5b6f41409186801300a75648e Mon Sep 17 00:00:00 2001 From: maxzod Date: Sun, 11 Sep 2022 16:04:32 +0200 Subject: [PATCH 1/3] add ability to rewind till the end --- example/android/app/build.gradle | 2 +- example/android/build.gradle | 2 +- example/pubspec.lock | 31 ++++++++++---------------- lib/src/swipable_stack.dart | 13 +++++------ lib/src/swipable_stack_controller.dart | 10 ++++----- pubspec.lock | 31 ++++++++++---------------- 6 files changed, 36 insertions(+), 53 deletions(-) diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 6ca2344..fc7c076 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -26,7 +26,7 @@ apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 30 + compileSdkVersion 31 sourceSets { main.java.srcDirs += 'src/main/kotlin' diff --git a/example/android/build.gradle b/example/android/build.gradle index c505a86..714549c 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.3.50' + ext.kotlin_version = '1.6.10' repositories { google() jcenter() diff --git a/example/pubspec.lock b/example/pubspec.lock index 5fa30a0..e756d06 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -7,7 +7,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.8.2" + version: "2.9.0" boolean_selector: dependency: transitive description: @@ -21,21 +21,14 @@ packages: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" + version: "1.2.1" clock: dependency: transitive description: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.1" collection: dependency: transitive description: @@ -49,7 +42,7 @@ packages: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.3.1" flutter: dependency: "direct main" description: flutter @@ -80,28 +73,28 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.11" + version: "0.12.12" material_color_utilities: dependency: transitive description: name: material_color_utilities url: "https://pub.dartlang.org" source: hosted - version: "0.1.4" + version: "0.1.5" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.8.0" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.1" + version: "1.8.2" pedantic_mono: dependency: "direct dev" description: @@ -120,7 +113,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.2" + version: "1.9.0" sprung: dependency: transitive description: @@ -148,7 +141,7 @@ packages: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.1" swipable_stack: dependency: "direct main" description: @@ -162,14 +155,14 @@ packages: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.2.1" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.9" + version: "0.4.12" vector_math: dependency: transitive description: diff --git a/lib/src/swipable_stack.dart b/lib/src/swipable_stack.dart index 33feb27..822d434 100644 --- a/lib/src/swipable_stack.dart +++ b/lib/src/swipable_stack.dart @@ -512,12 +512,11 @@ class _SwipableStackState extends State swipeProgress: swipeDirectionRate?.rate ?? 0.0, ), ); - final previousSession = widget.controller._previousSession; - if (previousSession != null) { + if (widget.controller.history.isNotEmpty) { cards.add( _SwipablePositioned( key: child.key ?? ValueKey(rewindTargetIndex), - session: previousSession, + session: widget.controller.history.last, index: -1, viewFraction: widget.viewFraction, swipeAnchor: widget.swipeAnchor, @@ -584,13 +583,11 @@ class _SwipableStackState extends State void _rewind({ required Duration duration, }) { - if (!canAnimationStart) { - return; - } - final previousSession = widget.controller._previousSession; - if (previousSession == null) { + if (widget.controller.history.isEmpty || !canAnimationStart) { return; } + final previousSession = widget.controller.history.last; + widget.controller._prepareRewind(); _rewindAnimationController.duration = duration; final rewindAnimation = _rewindAnimationController.tweenCurvedAnimation( diff --git a/lib/src/swipable_stack_controller.dart b/lib/src/swipable_stack_controller.dart index f5b6002..998388f 100644 --- a/lib/src/swipable_stack_controller.dart +++ b/lib/src/swipable_stack_controller.dart @@ -40,12 +40,12 @@ class SwipableStackController extends ChangeNotifier { void _initializeSessions() { _currentSessionState = null; - _previousSession = null; + history.removeLast(); notifyListeners(); } void _completeAction() { - _previousSession = currentSession?.copyWith(); + history.add(currentSession!.copyWith()); _currentIndex += 1; _currentSessionState = null; notifyListeners(); @@ -57,15 +57,15 @@ class SwipableStackController extends ChangeNotifier { } void _prepareRewind() { - _currentSessionState = _previousSession?.copyWith(); + _currentSessionState = history.last.copyWith(); _currentIndex -= 1; notifyListeners(); } - _SwipableStackPosition? _previousSession; + final history = <_SwipableStackPosition>[]; /// Whether to rewind. - bool get canRewind => _previousSession != null && _currentIndex > 0; + bool get canRewind => history.isNotEmpty; /// Advance to the next card with specified [swipeDirection]. /// diff --git a/pubspec.lock b/pubspec.lock index b9b4b72..97b203a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -7,7 +7,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.8.2" + version: "2.9.0" boolean_selector: dependency: transitive description: @@ -21,21 +21,14 @@ packages: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" + version: "1.2.1" clock: dependency: transitive description: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.1" collection: dependency: transitive description: @@ -49,7 +42,7 @@ packages: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.3.1" flutter: dependency: "direct main" description: flutter @@ -80,28 +73,28 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.11" + version: "0.12.12" material_color_utilities: dependency: transitive description: name: material_color_utilities url: "https://pub.dartlang.org" source: hosted - version: "0.1.4" + version: "0.1.5" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.8.0" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.1" + version: "1.8.2" pedantic_mono: dependency: "direct dev" description: @@ -120,7 +113,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.2" + version: "1.9.0" sprung: dependency: "direct main" description: @@ -148,21 +141,21 @@ packages: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.1" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.2.1" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.9" + version: "0.4.12" vector_math: dependency: transitive description: From 7dbdd9ec83ddf2975b14f5b664a73038a743d8d0 Mon Sep 17 00:00:00 2001 From: maxzod Date: Sun, 11 Sep 2022 17:19:34 +0200 Subject: [PATCH 2/3] add onSwipeForbiden --- example/lib/main.dart | 13 ++++++++++--- lib/src/model/swipe_rate_per_threshold.dart | 18 ++++++++++++++---- lib/src/swipable_stack.dart | 9 +++++++++ 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 7e28229..0728948 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -68,14 +68,21 @@ class _HomeState extends State { padding: const EdgeInsets.all(8), child: SwipableStack( detectableSwipeDirections: const { - SwipeDirection.right, - SwipeDirection.left, + // SwipeDirection.right, + // SwipeDirection.left, + SwipeDirection.up, + SwipeDirection.down, }, controller: _controller, stackClipBehaviour: Clip.none, + onSwipeForbiden: (index, direction) { + if (kDebugMode) { + print('onSwipeForbiden $index, $direction'); + } + }, onSwipeCompleted: (index, direction) { if (kDebugMode) { - print('$index, $direction'); + print('onSwipeCompleted $index, $direction'); } }, horizontalSwipeThreshold: 0.8, diff --git a/lib/src/model/swipe_rate_per_threshold.dart b/lib/src/model/swipe_rate_per_threshold.dart index 07e9b52..03f0a2d 100644 --- a/lib/src/model/swipe_rate_per_threshold.dart +++ b/lib/src/model/swipe_rate_per_threshold.dart @@ -94,6 +94,7 @@ extension _SwipableStackPositionX on _SwipableStackPosition { required double horizontalSwipeThreshold, required double verticalSwipeThreshold, required Set detectableDirections, + required ValueChanged isForbidden, }) { final directionRate = swipeDirectionRate( constraints: constraints, @@ -101,10 +102,19 @@ extension _SwipableStackPositionX on _SwipableStackPosition { verticalSwipeThreshold: verticalSwipeThreshold, detectableDirections: detectableDirections, ); - if (directionRate == null) { - return null; - } - if (directionRate.rate < 1) { + + if (directionRate == null || directionRate.rate < 1) { + final directionRateForbid = swipeDirectionRate( + constraints: constraints, + horizontalSwipeThreshold: horizontalSwipeThreshold, + verticalSwipeThreshold: verticalSwipeThreshold, + detectableDirections: SwipeDirection.values.toSet(), + ); + + if (directionRateForbid != null && directionRateForbid.rate >= 1) { + isForbidden(directionRate!.direction); + } + return null; } else { return directionRate.direction; diff --git a/lib/src/swipable_stack.dart b/lib/src/swipable_stack.dart index 822d434..2d54740 100644 --- a/lib/src/swipable_stack.dart +++ b/lib/src/swipable_stack.dart @@ -22,6 +22,7 @@ class SwipableStack extends StatefulWidget { required this.builder, SwipableStackController? controller, this.onSwipeCompleted, + this.onSwipeForbiden, this.onWillMoveNext, this.overlayBuilder, this.horizontalSwipeThreshold = _defaultHorizontalSwipeThreshold, @@ -58,6 +59,7 @@ class SwipableStack extends StatefulWidget { /// Callback called when the Swipe is completed. final SwipeCompletionCallback? onSwipeCompleted; + final SwipeCompletionCallback? onSwipeForbiden; /// Callback called just before launching the Swipe action. /// @@ -412,6 +414,12 @@ class _SwipableStackState extends State horizontalSwipeThreshold: widget.horizontalSwipeThreshold, verticalSwipeThreshold: widget.verticalSwipeThreshold, detectableDirections: widget.detectableSwipeDirections, + isForbidden: (dir) { + widget.onSwipeForbiden?.call( + _currentIndex, + dir, + ); + }, ); if (swipeAssistDirection == null) { @@ -425,6 +433,7 @@ class _SwipableStackState extends State true; if (!allowMoveNext) { _cancelSwipe(); + return; } _swipeNext(swipeAssistDirection); From 6a15a97403d8c4603d4c022d973dac0edc82c251 Mon Sep 17 00:00:00 2001 From: maxzod Date: Mon, 12 Sep 2022 13:54:53 +0200 Subject: [PATCH 3/3] fix onSwipeForbiden return real direction --- lib/src/model/swipe_rate_per_threshold.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/model/swipe_rate_per_threshold.dart b/lib/src/model/swipe_rate_per_threshold.dart index 03f0a2d..e9f5266 100644 --- a/lib/src/model/swipe_rate_per_threshold.dart +++ b/lib/src/model/swipe_rate_per_threshold.dart @@ -112,7 +112,7 @@ extension _SwipableStackPositionX on _SwipableStackPosition { ); if (directionRateForbid != null && directionRateForbid.rate >= 1) { - isForbidden(directionRate!.direction); + isForbidden(directionRateForbid.direction); } return null;