Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent modal sheet from poping while dragging #62

Merged
merged 4 commits into from
Mar 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions package/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 0.3.4 Mar 9, 2024

- Fix crash when clicking on the modal barrier while dragging the sheet (#54)

## 0.3.3 Feb 29, 2024

- Add `InterpolationSimulation` (#55)
Expand Down
20 changes: 16 additions & 4 deletions package/lib/src/foundation/sheet_activity.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import 'package:flutter/scheduler.dart';
import 'package:flutter/widgets.dart';
import 'package:smooth_sheets/src/foundation/notification.dart';
import 'package:smooth_sheets/src/foundation/sheet_extent.dart';
import 'package:smooth_sheets/src/foundation/sheet_status.dart';

abstract class SheetActivity extends ChangeNotifier {
bool _mounted = false;
Expand All @@ -24,6 +25,8 @@ abstract class SheetActivity extends ChangeNotifier {

double get velocity => 0.0;

SheetStatus get status;

@mustCallSuper
void initWith(SheetExtent delegate) {
assert(
Expand Down Expand Up @@ -147,7 +150,7 @@ abstract class SheetActivity extends ChangeNotifier {
}

class AnimatedSheetActivity extends SheetActivity
with DrivenSheetActivityMixin {
with ControlledSheetActivityMixin {
AnimatedSheetActivity({
required this.from,
required this.to,
Expand Down Expand Up @@ -178,7 +181,7 @@ class AnimatedSheetActivity extends SheetActivity
}

class BallisticSheetActivity extends SheetActivity
with DrivenSheetActivityMixin {
with ControlledSheetActivityMixin {
BallisticSheetActivity({
required this.simulation,
});
Expand All @@ -201,9 +204,12 @@ class BallisticSheetActivity extends SheetActivity
}
}

class IdleSheetActivity extends SheetActivity {}
class IdleSheetActivity extends SheetActivity {
@override
SheetStatus get status => SheetStatus.stable;
}

mixin DrivenSheetActivityMixin on SheetActivity {
mixin ControlledSheetActivityMixin on SheetActivity {
late final AnimationController controller;
late double _lastAnimatedValue;

Expand All @@ -217,6 +223,9 @@ mixin DrivenSheetActivityMixin on SheetActivity {
@override
double get velocity => controller.velocity;

@override
SheetStatus get status => SheetStatus.controlled;

@override
void initWith(SheetExtent delegate) {
super.initWith(delegate);
Expand Down Expand Up @@ -246,6 +255,9 @@ mixin DrivenSheetActivityMixin on SheetActivity {
}

mixin UserControlledSheetActivityMixin on SheetActivity {
@override
SheetStatus get status => SheetStatus.userControlled;

@override
void didFinalizeDimensions(
Size? oldContentDimensions,
Expand Down
25 changes: 19 additions & 6 deletions package/lib/src/foundation/sheet_extent.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import 'package:flutter/widgets.dart';
import 'package:smooth_sheets/src/draggable/draggable_sheet.dart';
import 'package:smooth_sheets/src/foundation/sheet_activity.dart';
import 'package:smooth_sheets/src/foundation/sheet_controller.dart';
import 'package:smooth_sheets/src/foundation/sheet_physics.dart';
import 'package:smooth_sheets/smooth_sheets.dart';
import 'package:smooth_sheets/src/foundation/sheet_status.dart';
import 'package:smooth_sheets/src/internal/double_utils.dart';
import 'package:smooth_sheets/src/scrollable/scrollable_sheet.dart';
import 'package:smooth_sheets/src/scrollable/scrollable_sheet_extent.dart';

/// A representation of a visible height of the sheet.
///
Expand Down Expand Up @@ -162,6 +158,9 @@ abstract class SheetExtent with ChangeNotifier, MaybeSheetMetrics {
return SheetMetricsSnapshot.from(metrics);
}

@override
SheetStatus get status => _activity!.status;

@override
double? get pixels => _activity!.pixels;

Expand Down Expand Up @@ -398,6 +397,9 @@ class ViewportDimensions {

/// A description of the state of a sheet.
mixin MaybeSheetMetrics {
/// The current status of the sheet.
SheetStatus get status;

/// The current extent of the sheet.
double? get pixels;

Expand Down Expand Up @@ -502,6 +504,7 @@ mixin SheetMetrics on MaybeSheetMetrics {
class SheetMetricsSnapshot with MaybeSheetMetrics, SheetMetrics {
/// Creates an immutable description of the sheet's state.
const SheetMetricsSnapshot({
required this.status,
required this.pixels,
required this.minPixels,
required this.maxPixels,
Expand All @@ -512,6 +515,7 @@ class SheetMetricsSnapshot with MaybeSheetMetrics, SheetMetrics {
/// Creates a snapshot of the given [SheetMetrics].
factory SheetMetricsSnapshot.from(SheetMetrics other) {
return SheetMetricsSnapshot(
status: other.status,
pixels: other.pixels,
minPixels: other.minPixels,
maxPixels: other.maxPixels,
Expand All @@ -520,6 +524,9 @@ class SheetMetricsSnapshot with MaybeSheetMetrics, SheetMetrics {
);
}

@override
final SheetStatus status;

@override
final double pixels;

Expand All @@ -539,14 +546,17 @@ class SheetMetricsSnapshot with MaybeSheetMetrics, SheetMetrics {
bool get hasPixels => true;

/// Creates a copy of this object with the given fields replaced.

SheetMetricsSnapshot copyWith({
SheetStatus? status,
double? pixels,
double? minPixels,
double? maxPixels,
Size? contentDimensions,
ViewportDimensions? viewportDimensions,
}) {
return SheetMetricsSnapshot(
status: status ?? this.status,
pixels: pixels ?? this.pixels,
minPixels: minPixels ?? this.minPixels,
maxPixels: maxPixels ?? this.maxPixels,
Expand Down Expand Up @@ -593,6 +603,9 @@ class _SheetMetricsRef with MaybeSheetMetrics, SheetMetrics {

final MaybeSheetMetrics _source;

@override
SheetStatus get status => _source.status;

@override
double get pixels => _source.pixels!;

Expand Down
11 changes: 11 additions & 0 deletions package/lib/src/foundation/sheet_status.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/// The status of a sheet.
enum SheetStatus {
/// The sheet is resting at a natural position.
stable,

/// The sheet position is controlled by a programmatic way such as animation.
controlled,

/// The sheet position is controlled by a user gesture such as dragging.
userControlled,
}
37 changes: 36 additions & 1 deletion package/lib/src/modal/modal_sheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:smooth_sheets/src/foundation/sheet_controller.dart';
import 'package:smooth_sheets/src/foundation/sheet_status.dart';
import 'package:smooth_sheets/src/internal/double_utils.dart';
import 'package:smooth_sheets/src/internal/monodrag.dart';

Expand Down Expand Up @@ -185,6 +186,40 @@ mixin ModalSheetRouteMixin<T> on ModalRoute<T> {
child: child,
);
}

@override
Widget buildModalBarrier() {
void onDismiss() {
if (animation!.status == AnimationStatus.completed &&
sheetController.metrics?.status == SheetStatus.stable) {
navigator?.maybePop();
}
}

final barrierColor = this.barrierColor;
if (barrierColor != null && barrierColor.alpha != 0 && !offstage) {
assert(barrierColor != barrierColor.withOpacity(0.0));
return AnimatedModalBarrier(
onDismiss: onDismiss,
dismissible: barrierDismissible,
semanticsLabel: barrierLabel,
barrierSemanticsDismissible: semanticsDismissible,
color: animation!.drive(
ColorTween(
begin: barrierColor.withOpacity(0.0),
end: barrierColor,
).chain(CurveTween(curve: barrierCurve)),
),
);
} else {
return ModalBarrier(
onDismiss: onDismiss,
dismissible: barrierDismissible,
semanticsLabel: barrierLabel,
barrierSemanticsDismissible: semanticsDismissible,
);
}
}
}

class SheetDismissible extends StatefulWidget {
Expand Down Expand Up @@ -231,7 +266,7 @@ class _SheetDismissibleState extends State<SheetDismissible> {
super.didChangeDependencies();
_gestureRecognizer.gestureSettings =
MediaQuery.maybeGestureSettingsOf(context);
_sheetController = DefaultSheetController.of(context);
_sheetController = SheetControllerScope.of(context);

assert(
ModalRoute.of(context) is ModalSheetRouteMixin<dynamic>,
Expand Down
4 changes: 4 additions & 0 deletions package/lib/src/navigation/navigation_route.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:smooth_sheets/src/foundation/framework.dart';
import 'package:smooth_sheets/src/foundation/sheet_activity.dart';
import 'package:smooth_sheets/src/foundation/sheet_extent.dart';
import 'package:smooth_sheets/src/foundation/sheet_status.dart';
import 'package:smooth_sheets/src/navigation/navigation_sheet.dart';

mixin NavigationSheetRouteMixin<T> on NavigationSheetRoute<T> {
Expand Down Expand Up @@ -109,6 +110,9 @@ class _SheetExtentBox extends ChangeNotifier
super.dispose();
}

@override
SheetStatus get status => _source?.status ?? SheetStatus.stable;

@override
double? get pixels => _source?.pixels;

Expand Down
8 changes: 8 additions & 0 deletions package/lib/src/navigation/navigation_sheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'package:smooth_sheets/src/foundation/sheet_activity.dart';
import 'package:smooth_sheets/src/foundation/sheet_controller.dart';
import 'package:smooth_sheets/src/foundation/sheet_extent.dart';
import 'package:smooth_sheets/src/foundation/sheet_physics.dart';
import 'package:smooth_sheets/src/foundation/sheet_status.dart';
import 'package:smooth_sheets/src/internal/transition_observer.dart';

typedef NavigationSheetTransitionObserver = TransitionObserver;
Expand Down Expand Up @@ -128,6 +129,7 @@ abstract class NavigationSheetExtentDelegate implements Listenable {
double? get pixels;
double? get minPixels;
double? get maxPixels;
SheetStatus get status;
void applyNewViewportDimensions(ViewportDimensions viewportDimensions);
void beginActivity(SheetActivity activity);
}
Expand Down Expand Up @@ -237,6 +239,9 @@ class _TransitionSheetActivity extends SheetActivity {

late final Animation<double> _curvedAnimation;

@override
SheetStatus get status => SheetStatus.controlled;

@override
void initWith(SheetExtent target) {
super.initWith(target);
Expand Down Expand Up @@ -268,6 +273,9 @@ class _ProxySheetActivity extends SheetActivity {

final NavigationSheetExtentDelegate target;

@override
SheetStatus get status => target.status;

@override
double? get pixels {
if (target.pixels != null) {
Expand Down
7 changes: 7 additions & 0 deletions package/lib/src/scrollable/scrollable_sheet_extent.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
import 'package:smooth_sheets/src/foundation/sheet_activity.dart';
import 'package:smooth_sheets/src/foundation/sheet_extent.dart';
import 'package:smooth_sheets/src/foundation/sheet_physics.dart';
import 'package:smooth_sheets/src/foundation/sheet_status.dart';
import 'package:smooth_sheets/src/foundation/sized_content_sheet.dart';
import 'package:smooth_sheets/src/internal/double_utils.dart';
import 'package:smooth_sheets/src/internal/into.dart';
Expand Down Expand Up @@ -242,6 +243,9 @@ class _ContentIdleScrollDrivenSheetActivity

final Extent initialExtent;

@override
SheetStatus get status => SheetStatus.stable;

@override
void didChangeContentDimensions(Size? oldDimensions) {
super.didChangeContentDimensions(oldDimensions);
Expand Down Expand Up @@ -288,6 +292,9 @@ class _ContentUserScrollDrivenSheetActivity

class _ContentBallisticScrollDrivenSheetActivity
extends _ContentScrollDrivenSheetActivity {
@override
SheetStatus get status => SheetStatus.controlled;

@override
DelegationResult<double> applyBallisticScrollOffset(
double delta,
Expand Down
2 changes: 1 addition & 1 deletion package/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: smooth_sheets
description: Sheet widgets with smooth motion and great flexibility. Also supports nested navigation in both imperative and declarative ways.
version: 0.3.3
version: 0.3.4
repository: https://github.com/fujidaiti/smooth_sheets

environment:
Expand Down
2 changes: 2 additions & 0 deletions package/test/foundation/sheet_physics_test.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:smooth_sheets/smooth_sheets.dart';
import 'package:smooth_sheets/src/foundation/sheet_status.dart';

class _SheetPhysicsWithDefaultConfiguration extends SheetPhysics {
const _SheetPhysicsWithDefaultConfiguration();
}

const _referenceSheetMetrics = SheetMetricsSnapshot(
status: SheetStatus.stable,
minPixels: 0,
maxPixels: 600,
pixels: 600,
Expand Down
Loading