Skip to content

Commit

Permalink
Implement dismissible page
Browse files Browse the repository at this point in the history
  • Loading branch information
cp-pratik-k committed Apr 8, 2024
1 parent 6977863 commit 67e4cce
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 78 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:data/models/media/media.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:style/extensions/context_extensions.dart';
import '../../../../components/error_view.dart';

Expand All @@ -14,11 +15,14 @@ class DownloadRequireView extends StatelessWidget {
child: Stack(
alignment: Alignment.center,
children: [
Image.network(
height: double.infinity,
width: double.infinity,
media.thumbnailLink!,
fit: BoxFit.cover,
Hero(
tag: media,
child: Image.network(
height: double.infinity,
width: double.infinity,
media.thumbnailLink!,
fit: BoxFit.cover,
),
),
Container(
color: Colors.black38,
Expand Down
85 changes: 12 additions & 73 deletions app/lib/ui/flow/media_preview/media_preview_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import 'package:style/extensions/context_extensions.dart';
import 'package:style/indicators/circular_progress_indicator.dart';
import 'package:video_player/video_player.dart';
import 'components/video_player_components/video_duration_slider.dart';
import 'package:style/animations/dismissible_page.dart';

class MediaPreview extends ConsumerStatefulWidget {
final List<AppMedia> medias;
Expand Down Expand Up @@ -124,6 +125,7 @@ class _MediaPreviewState extends ConsumerState<MediaPreview> {
ref.watch(_provider.select((state) => state.showActions));

return DismissiblePage(
backgroundColor: context.colorScheme.surface,
onProgress: (progress) {
if (progress > 0 && showActions) {
notifier.toggleActionVisibility();
Expand All @@ -132,7 +134,10 @@ class _MediaPreviewState extends ConsumerState<MediaPreview> {
onDismiss: () {
context.pop();
},
child: AppPage(
child: (progress) => AppPage(
backgroundColor: progress == 0
? context.colorScheme.surface
: Colors.transparent,
body: Stack(
children: [
GestureDetector(
Expand Down Expand Up @@ -170,9 +175,12 @@ class _MediaPreviewState extends ConsumerState<MediaPreview> {
color: context.colorScheme.onPrimary,
);
} else {
return AspectRatio(
aspectRatio: _videoPlayerController!.value.aspectRatio,
child: VideoPlayer(_videoPlayerController!),
return Hero(
tag: media,
child: AspectRatio(
aspectRatio: _videoPlayerController!.value.aspectRatio,
child: VideoPlayer(_videoPlayerController!),
),
);
}
}),
Expand Down Expand Up @@ -256,72 +264,3 @@ class _MediaPreviewState extends ConsumerState<MediaPreview> {
});
}

class DismissiblePage extends StatefulWidget {
final Widget child;
final double threshold;
final void Function(double progress)? onProgress;
final void Function()? onDismiss;
final double scaleDownPercentage;

const DismissiblePage({
Key? key,
required this.child,
this.threshold = 200,
this.onProgress,
this.onDismiss,
this.scaleDownPercentage = 0.25,
}) : super(key: key);

@override
State<DismissiblePage> createState() => _DismissiblePageState();
}

class _DismissiblePageState extends State<DismissiblePage> {
double _startY = 0.0;
double displacement = 0.0;
double percentage = 0.0;

@override
Widget build(BuildContext context) {
return GestureDetector(
onVerticalDragStart: (DragStartDetails details) {
_startY = details.globalPosition.dy;
},
onVerticalDragUpdate: (DragUpdateDetails details) {
if ((details.globalPosition.dy - _startY) > 0) {
setState(() {
displacement = details.globalPosition.dy - _startY;
percentage = (displacement / widget.threshold).clamp(0, 1);
});
}
widget.onProgress?.call(percentage);
},
onVerticalDragEnd: (DragEndDetails details) {
if (displacement > widget.threshold) {
widget.onDismiss?.call();
} else {
setState(() {
displacement = 0.0;
percentage = 0.0;
});
}
},
child: Stack(
children: [
Container(
color: Colors.black.withOpacity(1 - percentage),
height: double.infinity,
width: double.infinity,
),
Transform.translate(
offset: Offset(0, displacement),
child: Transform.scale(
scale: 1 - (percentage * widget.scaleDownPercentage),
child: widget.child,
),
),
],
),
);
}
}
76 changes: 76 additions & 0 deletions style/lib/animations/dismissible_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import 'package:flutter/cupertino.dart';

class DismissiblePage extends StatefulWidget {
final Widget Function(double progress) child;
final double threshold;
final Color backgroundColor;
final bool enable;
final void Function(double progress)? onProgress;
final void Function()? onDismiss;
final double scaleDownPercentage;

const DismissiblePage({
Key? key,
required this.child,
this.threshold = 100,
this.onProgress,
this.enable = true,
this.onDismiss,
this.scaleDownPercentage = 0.25,
this.backgroundColor = const Color(0xff000000),
}) : super(key: key);

@override
State<DismissiblePage> createState() => _DismissiblePageState();
}

class _DismissiblePageState extends State<DismissiblePage> {
double _startY = 0.0;
double displacement = 0.0;
double percentage = 0.0;

@override
Widget build(BuildContext context) {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onVerticalDragStart: (DragStartDetails details) {
_startY = details.globalPosition.dy;
},
onVerticalDragUpdate: (DragUpdateDetails details) {
if ((details.globalPosition.dy - _startY) > 0 && widget.enable) {
setState(() {
displacement = details.globalPosition.dy - _startY;
percentage = (displacement / widget.threshold).clamp(0, 1);
});
widget.onProgress?.call(percentage);
}
},
onVerticalDragEnd: (DragEndDetails details) {
if (displacement > widget.threshold) {
widget.onDismiss?.call();
} else {
setState(() {
displacement = 0.0;
percentage = 0.0;
});
}
},
child: Stack(
children: [
Container(
color: widget.backgroundColor.withOpacity(1 - percentage),
height: double.infinity,
width: double.infinity,
),
Transform.translate(
offset: Offset(0, displacement),
child: Transform.scale(
scale: 1 - (percentage * widget.scaleDownPercentage),
child: widget.child(percentage),
),
),
],
),
);
}
}

0 comments on commit 67e4cce

Please sign in to comment.