Compare commits
7 commits
main
...
fix/motion
Author | SHA1 | Date | |
---|---|---|---|
|
292e44ded7 | ||
|
fba940335c | ||
|
6161122e9e | ||
|
b6d667c5d8 | ||
|
753bc84354 | ||
|
dd7dadc694 | ||
|
1242754690 |
7 changed files with 198 additions and 68 deletions
|
@ -244,7 +244,7 @@ class GalleryViewerPage extends HookConsumerWidget {
|
|||
);
|
||||
}
|
||||
|
||||
void handleSwipeUpDown(DragUpdateDetails details) {
|
||||
void handleDragUpdate(Asset asset, DragUpdateDetails details) {
|
||||
int sensitivity = 15;
|
||||
int dxThreshold = 50;
|
||||
|
||||
|
@ -373,6 +373,33 @@ class GalleryViewerPage extends HookConsumerWidget {
|
|||
);
|
||||
}
|
||||
|
||||
/// The image provider to use for the given asset
|
||||
ImageProvider imageProvider(Asset asset) {
|
||||
// Local assets
|
||||
if (asset.isLocal) {
|
||||
return localImageProvider(asset);
|
||||
}
|
||||
|
||||
// Original assets
|
||||
if (isLoadOriginal.value) {
|
||||
return originalImageProvider(asset);
|
||||
}
|
||||
|
||||
// Preview uses remote JPEG
|
||||
if (isLoadPreview.value) {
|
||||
return remoteThumbnailImageProvider(
|
||||
asset,
|
||||
api.ThumbnailFormat.JPEG,
|
||||
);
|
||||
}
|
||||
|
||||
// Otherwise, use the thumbnail preview
|
||||
return remoteThumbnailImageProvider(
|
||||
asset,
|
||||
api.ThumbnailFormat.WEBP,
|
||||
);
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.black,
|
||||
body: WillPopScope(
|
||||
|
@ -466,31 +493,15 @@ class GalleryViewerPage extends HookConsumerWidget {
|
|||
: null,
|
||||
builder: (context, index) {
|
||||
getAssetExif();
|
||||
// Create image provider
|
||||
final ImageProvider provider = imageProvider(assetList[index]);
|
||||
|
||||
if (assetList[index].isImage && !isPlayingMotionVideo.value) {
|
||||
// Show photo
|
||||
final ImageProvider provider;
|
||||
if (assetList[index].isLocal) {
|
||||
provider = localImageProvider(assetList[index]);
|
||||
} else {
|
||||
if (isLoadOriginal.value) {
|
||||
provider = originalImageProvider(assetList[index]);
|
||||
} else if (isLoadPreview.value) {
|
||||
provider = remoteThumbnailImageProvider(
|
||||
assetList[index],
|
||||
api.ThumbnailFormat.JPEG,
|
||||
);
|
||||
} else {
|
||||
provider = remoteThumbnailImageProvider(
|
||||
assetList[index],
|
||||
api.ThumbnailFormat.WEBP,
|
||||
);
|
||||
}
|
||||
}
|
||||
return PhotoViewGalleryPageOptions(
|
||||
onDragStart: (_, details, __) =>
|
||||
localPosition = details.localPosition,
|
||||
onDragUpdate: (_, details, __) =>
|
||||
handleSwipeUpDown(details),
|
||||
handleDragUpdate(assetList[index], details),
|
||||
onTapDown: (_, __, ___) =>
|
||||
showAppBar.value = !showAppBar.value,
|
||||
imageProvider: provider,
|
||||
|
@ -510,7 +521,7 @@ class GalleryViewerPage extends HookConsumerWidget {
|
|||
onDragStart: (_, details, __) =>
|
||||
localPosition = details.localPosition,
|
||||
onDragUpdate: (_, details, __) =>
|
||||
handleSwipeUpDown(details),
|
||||
handleDragUpdate(assetList[index], details),
|
||||
heroAttributes: PhotoViewHeroAttributes(
|
||||
tag: assetList[index].id,
|
||||
),
|
||||
|
@ -518,23 +529,47 @@ class GalleryViewerPage extends HookConsumerWidget {
|
|||
maxScale: 1.0,
|
||||
minScale: 1.0,
|
||||
basePosition: Alignment.bottomCenter,
|
||||
child: SafeArea(
|
||||
child: VideoViewerPage(
|
||||
onPlaying: () => isPlayingVideo.value = true,
|
||||
onPaused: () => isPlayingVideo.value = false,
|
||||
asset: assetList[index],
|
||||
isMotionVideo: isPlayingMotionVideo.value,
|
||||
onVideoEnded: () {
|
||||
if (isPlayingMotionVideo.value) {
|
||||
isPlayingMotionVideo.value = false;
|
||||
}
|
||||
},
|
||||
child: VideoViewerPage(
|
||||
onPlaying: () => isPlayingVideo.value = true,
|
||||
onPaused: () => isPlayingVideo.value = false,
|
||||
asset: assetList[index],
|
||||
isMotionVideo: isPlayingMotionVideo.value,
|
||||
placeholder: Image(
|
||||
image: provider,
|
||||
fit: BoxFit.fitWidth,
|
||||
height: MediaQuery.of(context).size.height,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
onVideoEnded: () {
|
||||
if (isPlayingMotionVideo.value) {
|
||||
isPlayingMotionVideo.value = false;
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
GestureDetector(
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onLongPressStart: (_) {
|
||||
// If we are a motion video and we are not playing, start playing
|
||||
if (assetList[indexOfAsset.value].livePhotoVideoId != null &&
|
||||
!isPlayingMotionVideo.value) {
|
||||
isPlayingMotionVideo.value = true;
|
||||
}
|
||||
},
|
||||
onLongPressEnd: (_) {
|
||||
// Stop playing the motion video if this is a video and we are
|
||||
// playing
|
||||
if (assetList[indexOfAsset.value].livePhotoVideoId != null &&
|
||||
isPlayingMotionVideo.value) {
|
||||
isPlayingMotionVideo.value = false;
|
||||
}
|
||||
},
|
||||
child: const SizedBox.expand(),
|
||||
),
|
||||
Positioned(
|
||||
top: 0,
|
||||
left: 0,
|
||||
|
|
|
@ -15,6 +15,7 @@ import 'package:video_player/video_player.dart';
|
|||
class VideoViewerPage extends HookConsumerWidget {
|
||||
final Asset asset;
|
||||
final bool isMotionVideo;
|
||||
final Widget? placeholder;
|
||||
final VoidCallback onVideoEnded;
|
||||
final VoidCallback? onPlaying;
|
||||
final VoidCallback? onPaused;
|
||||
|
@ -26,6 +27,7 @@ class VideoViewerPage extends HookConsumerWidget {
|
|||
required this.onVideoEnded,
|
||||
this.onPlaying,
|
||||
this.onPaused,
|
||||
this.placeholder,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
@ -66,6 +68,7 @@ class VideoViewerPage extends HookConsumerWidget {
|
|||
onVideoEnded: onVideoEnded,
|
||||
onPaused: onPaused,
|
||||
onPlaying: onPlaying,
|
||||
placeholder: placeholder,
|
||||
),
|
||||
if (downloadAssetStatus == DownloadAssetStatus.loading)
|
||||
const Center(
|
||||
|
@ -95,6 +98,10 @@ class VideoPlayer extends StatefulWidget {
|
|||
final Function()? onPlaying;
|
||||
final Function()? onPaused;
|
||||
|
||||
/// The placeholder to show while the video is loading usually, a thumbnail
|
||||
/// of the video
|
||||
final Widget? placeholder;
|
||||
|
||||
const VideoPlayer({
|
||||
Key? key,
|
||||
this.url,
|
||||
|
@ -104,6 +111,7 @@ class VideoPlayer extends StatefulWidget {
|
|||
required this.isMotionVideo,
|
||||
this.onPlaying,
|
||||
this.onPaused,
|
||||
this.placeholder,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
@ -186,12 +194,33 @@ class _VideoPlayerState extends State<VideoPlayer> {
|
|||
),
|
||||
);
|
||||
} else {
|
||||
return const Center(
|
||||
child: SizedBox(
|
||||
width: 75,
|
||||
height: 75,
|
||||
child: CircularProgressIndicator.adaptive(
|
||||
strokeWidth: 2,
|
||||
return SizedBox(
|
||||
height: MediaQuery.of(context).size.height,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: Center(
|
||||
child: Stack(
|
||||
children: [
|
||||
if (widget.placeholder != null) widget.placeholder!,
|
||||
FutureBuilder(
|
||||
future: Future.delayed(const Duration(seconds: 1)),
|
||||
builder: (context, snapshot) {
|
||||
// If we have to wait for over 1 second to start the video
|
||||
// then show the loading indicator
|
||||
final loading =
|
||||
(snapshot.connectionState == ConnectionState.done)
|
||||
? const Center(
|
||||
child: ImmichLoadingIndicator(),
|
||||
)
|
||||
: Container();
|
||||
|
||||
// Fade in the loading animation
|
||||
return AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: loading,
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -253,6 +253,8 @@ class PhotoView extends StatefulWidget {
|
|||
this.onTapDown,
|
||||
this.onDragStart,
|
||||
this.onDragEnd,
|
||||
this.onLongPressStart,
|
||||
this.onLongPressEnd,
|
||||
this.onDragUpdate,
|
||||
this.onScaleEnd,
|
||||
this.customSize,
|
||||
|
@ -293,6 +295,8 @@ class PhotoView extends StatefulWidget {
|
|||
this.onDragStart,
|
||||
this.onDragEnd,
|
||||
this.onDragUpdate,
|
||||
this.onLongPressStart,
|
||||
this.onLongPressEnd,
|
||||
this.onScaleEnd,
|
||||
this.customSize,
|
||||
this.gestureDetectorBehavior,
|
||||
|
@ -397,6 +401,12 @@ class PhotoView extends StatefulWidget {
|
|||
/// location.
|
||||
final PhotoViewImageDragUpdateCallback? onDragUpdate;
|
||||
|
||||
/// A long press start event
|
||||
final PhotoViewImageLongPressStartCallback? onLongPressStart;
|
||||
|
||||
/// A long press end event
|
||||
final PhotoViewImageLongPressEndCallback? onLongPressEnd;
|
||||
|
||||
/// A pointer that will trigger a scale has stopped contacting the screen at a
|
||||
/// particular location.
|
||||
final PhotoViewImageScaleEndCallback? onScaleEnd;
|
||||
|
@ -534,6 +544,8 @@ class _PhotoViewState extends State<PhotoView>
|
|||
onDragStart: widget.onDragStart,
|
||||
onDragEnd: widget.onDragEnd,
|
||||
onDragUpdate: widget.onDragUpdate,
|
||||
onLongPressStart: widget.onLongPressStart,
|
||||
onLongPressEnd: widget.onLongPressEnd,
|
||||
onScaleEnd: widget.onScaleEnd,
|
||||
outerSize: computedOuterSize,
|
||||
gestureDetectorBehavior: widget.gestureDetectorBehavior,
|
||||
|
@ -563,6 +575,8 @@ class _PhotoViewState extends State<PhotoView>
|
|||
onDragStart: widget.onDragStart,
|
||||
onDragEnd: widget.onDragEnd,
|
||||
onDragUpdate: widget.onDragUpdate,
|
||||
onLongPressStart: widget.onLongPressStart,
|
||||
onLongPressEnd: widget.onLongPressEnd,
|
||||
onScaleEnd: widget.onScaleEnd,
|
||||
outerSize: computedOuterSize,
|
||||
gestureDetectorBehavior: widget.gestureDetectorBehavior,
|
||||
|
@ -625,7 +639,7 @@ typedef PhotoViewImageDragStartCallback = Function(
|
|||
PhotoViewControllerValue controllerValue,
|
||||
);
|
||||
|
||||
/// A type definition for a callback when the user drags
|
||||
/// A type definition for a callback when the user drags
|
||||
typedef PhotoViewImageDragUpdateCallback = Function(
|
||||
BuildContext context,
|
||||
DragUpdateDetails details,
|
||||
|
@ -646,6 +660,20 @@ typedef PhotoViewImageScaleEndCallback = Function(
|
|||
PhotoViewControllerValue controllerValue,
|
||||
);
|
||||
|
||||
/// A type definition for a callback when the user starts a long press
|
||||
typedef PhotoViewImageLongPressStartCallback = Function(
|
||||
BuildContext context,
|
||||
LongPressStartDetails details,
|
||||
PhotoViewControllerValue controllerValue,
|
||||
);
|
||||
|
||||
/// A type definition for a callback when the user starts a long press
|
||||
typedef PhotoViewImageLongPressEndCallback = Function(
|
||||
BuildContext context,
|
||||
LongPressEndDetails details,
|
||||
PhotoViewControllerValue controllerValue,
|
||||
);
|
||||
|
||||
/// A type definition for a callback to show a widget while the image is loading, a [ImageChunkEvent] is passed to inform progress
|
||||
typedef LoadingBuilder = Widget Function(
|
||||
BuildContext context,
|
||||
|
|
|
@ -3,16 +3,7 @@ library photo_view_gallery;
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:immich_mobile/shared/ui/photo_view/photo_view.dart'
|
||||
show
|
||||
LoadingBuilder,
|
||||
PhotoView,
|
||||
PhotoViewImageTapDownCallback,
|
||||
PhotoViewImageTapUpCallback,
|
||||
PhotoViewImageDragStartCallback,
|
||||
PhotoViewImageDragEndCallback,
|
||||
PhotoViewImageDragUpdateCallback,
|
||||
PhotoViewImageScaleEndCallback,
|
||||
ScaleStateCycle;
|
||||
show LoadingBuilder, PhotoView, PhotoViewImageDragEndCallback, PhotoViewImageDragStartCallback, PhotoViewImageDragUpdateCallback, PhotoViewImageLongPressEndCallback, PhotoViewImageLongPressStartCallback, PhotoViewImageScaleEndCallback, PhotoViewImageTapDownCallback, PhotoViewImageTapUpCallback, ScaleStateCycle;
|
||||
|
||||
import 'package:immich_mobile/shared/ui/photo_view/src/controller/photo_view_controller.dart';
|
||||
import 'package:immich_mobile/shared/ui/photo_view/src/controller/photo_view_scalestate_controller.dart';
|
||||
|
@ -25,7 +16,7 @@ typedef PhotoViewGalleryPageChangedCallback = void Function(int index);
|
|||
|
||||
/// A type definition for a [Function] that defines a page in [PhotoViewGallery.build]
|
||||
typedef PhotoViewGalleryBuilder = PhotoViewGalleryPageOptions Function(
|
||||
BuildContext context,
|
||||
BuildContext context,
|
||||
int index,
|
||||
);
|
||||
|
||||
|
@ -270,6 +261,8 @@ class _PhotoViewGalleryState extends State<PhotoViewGallery> {
|
|||
onDragStart: pageOption.onDragStart,
|
||||
onDragEnd: pageOption.onDragEnd,
|
||||
onDragUpdate: pageOption.onDragUpdate,
|
||||
onLongPressStart: pageOption.onLongPressStart,
|
||||
onLongPressEnd: pageOption.onLongPressEnd,
|
||||
onScaleEnd: pageOption.onScaleEnd,
|
||||
gestureDetectorBehavior: pageOption.gestureDetectorBehavior,
|
||||
tightMode: pageOption.tightMode,
|
||||
|
@ -299,6 +292,8 @@ class _PhotoViewGalleryState extends State<PhotoViewGallery> {
|
|||
onDragStart: pageOption.onDragStart,
|
||||
onDragEnd: pageOption.onDragEnd,
|
||||
onDragUpdate: pageOption.onDragUpdate,
|
||||
onLongPressStart: pageOption.onLongPressStart,
|
||||
onLongPressEnd: pageOption.onLongPressEnd,
|
||||
onScaleEnd: pageOption.onScaleEnd,
|
||||
gestureDetectorBehavior: pageOption.gestureDetectorBehavior,
|
||||
tightMode: pageOption.tightMode,
|
||||
|
@ -355,6 +350,8 @@ class PhotoViewGalleryPageOptions {
|
|||
this.onDragStart,
|
||||
this.onDragEnd,
|
||||
this.onDragUpdate,
|
||||
this.onLongPressStart,
|
||||
this.onLongPressEnd,
|
||||
this.onScaleEnd,
|
||||
this.gestureDetectorBehavior,
|
||||
this.tightMode,
|
||||
|
@ -381,6 +378,8 @@ class PhotoViewGalleryPageOptions {
|
|||
this.onDragStart,
|
||||
this.onDragEnd,
|
||||
this.onDragUpdate,
|
||||
this.onLongPressStart,
|
||||
this.onLongPressEnd,
|
||||
this.onScaleEnd,
|
||||
this.gestureDetectorBehavior,
|
||||
this.tightMode,
|
||||
|
@ -431,9 +430,15 @@ class PhotoViewGalleryPageOptions {
|
|||
/// Mirror to [PhotoView.onDragDown]
|
||||
final PhotoViewImageDragEndCallback? onDragEnd;
|
||||
|
||||
/// Mirror to [PhotoView.onDraUpdate]
|
||||
/// Mirror to [PhotoView.onDragUpdate]
|
||||
final PhotoViewImageDragUpdateCallback? onDragUpdate;
|
||||
|
||||
/// Mirror to [PhotoView.onLongPressStart]
|
||||
final PhotoViewImageLongPressStartCallback? onLongPressStart;
|
||||
|
||||
/// Mirror to [PhotoView.onLongPressStart]
|
||||
final PhotoViewImageLongPressEndCallback? onLongPressEnd;
|
||||
|
||||
/// Mirror to [PhotoView.onTapDown]
|
||||
final PhotoViewImageTapDownCallback? onTapDown;
|
||||
|
||||
|
|
|
@ -1,15 +1,6 @@
|
|||
import 'package:flutter/widgets.dart';
|
||||
import 'package:immich_mobile/shared/ui/photo_view/photo_view.dart'
|
||||
show
|
||||
PhotoViewScaleState,
|
||||
PhotoViewHeroAttributes,
|
||||
PhotoViewImageTapDownCallback,
|
||||
PhotoViewImageTapUpCallback,
|
||||
PhotoViewImageScaleEndCallback,
|
||||
PhotoViewImageDragEndCallback,
|
||||
PhotoViewImageDragStartCallback,
|
||||
PhotoViewImageDragUpdateCallback,
|
||||
ScaleStateCycle;
|
||||
show PhotoViewHeroAttributes, PhotoViewImageDragEndCallback, PhotoViewImageDragStartCallback, PhotoViewImageDragUpdateCallback, PhotoViewImageLongPressEndCallback, PhotoViewImageLongPressStartCallback, PhotoViewImageScaleEndCallback, PhotoViewImageTapDownCallback, PhotoViewImageTapUpCallback, PhotoViewScaleState, ScaleStateCycle;
|
||||
import 'package:immich_mobile/shared/ui/photo_view/src/controller/photo_view_controller.dart';
|
||||
import 'package:immich_mobile/shared/ui/photo_view/src/controller/photo_view_controller_delegate.dart';
|
||||
import 'package:immich_mobile/shared/ui/photo_view/src/controller/photo_view_scalestate_controller.dart';
|
||||
|
@ -36,6 +27,8 @@ class PhotoViewCore extends StatefulWidget {
|
|||
required this.onDragStart,
|
||||
required this.onDragEnd,
|
||||
required this.onDragUpdate,
|
||||
required this.onLongPressStart,
|
||||
required this.onLongPressEnd,
|
||||
required this.onScaleEnd,
|
||||
required this.gestureDetectorBehavior,
|
||||
required this.controller,
|
||||
|
@ -61,6 +54,8 @@ class PhotoViewCore extends StatefulWidget {
|
|||
this.onDragStart,
|
||||
this.onDragEnd,
|
||||
this.onDragUpdate,
|
||||
this.onLongPressStart,
|
||||
this.onLongPressEnd,
|
||||
this.onScaleEnd,
|
||||
this.gestureDetectorBehavior,
|
||||
required this.controller,
|
||||
|
@ -97,6 +92,9 @@ class PhotoViewCore extends StatefulWidget {
|
|||
final PhotoViewImageDragEndCallback? onDragEnd;
|
||||
final PhotoViewImageDragUpdateCallback? onDragUpdate;
|
||||
|
||||
final PhotoViewImageLongPressStartCallback? onLongPressStart;
|
||||
final PhotoViewImageLongPressEndCallback? onLongPressEnd;
|
||||
|
||||
final HitTestBehavior? gestureDetectorBehavior;
|
||||
final bool tightMode;
|
||||
final bool disableGestures;
|
||||
|
@ -359,13 +357,13 @@ class PhotoViewCoreState extends State<PhotoViewCore>
|
|||
onScaleStart: onScaleStart,
|
||||
onScaleUpdate: onScaleUpdate,
|
||||
onScaleEnd: onScaleEnd,
|
||||
onDragStart: widget.onDragStart != null
|
||||
onDragStart: widget.onDragStart != null
|
||||
? (details) => widget.onDragStart!(context, details, value)
|
||||
: null,
|
||||
onDragEnd: widget.onDragEnd != null
|
||||
onDragEnd: widget.onDragEnd != null
|
||||
? (details) => widget.onDragEnd!(context, details, value)
|
||||
: null,
|
||||
onDragUpdate: widget.onDragUpdate != null
|
||||
onDragUpdate: widget.onDragUpdate != null
|
||||
? (details) => widget.onDragUpdate!(context, details, value)
|
||||
: null,
|
||||
hitDetector: this,
|
||||
|
@ -375,6 +373,12 @@ class PhotoViewCoreState extends State<PhotoViewCore>
|
|||
onTapDown: widget.onTapDown != null
|
||||
? (details) => widget.onTapDown!(context, details, value)
|
||||
: null,
|
||||
onLongPressStart: widget.onLongPressStart != null
|
||||
? (details) => widget.onLongPressStart!(context, details, value)
|
||||
: null,
|
||||
onLongPressEnd: widget.onLongPressEnd != null
|
||||
? (details) => widget.onLongPressEnd!(context, details, value)
|
||||
: null,
|
||||
child: child,
|
||||
);
|
||||
} else {
|
||||
|
|
|
@ -16,6 +16,8 @@ class PhotoViewGestureDetector extends StatelessWidget {
|
|||
this.onDragStart,
|
||||
this.onDragEnd,
|
||||
this.onDragUpdate,
|
||||
this.onLongPressStart,
|
||||
this.onLongPressEnd,
|
||||
this.child,
|
||||
this.onTapUp,
|
||||
this.onTapDown,
|
||||
|
@ -36,6 +38,9 @@ class PhotoViewGestureDetector extends StatelessWidget {
|
|||
final GestureTapUpCallback? onTapUp;
|
||||
final GestureTapDownCallback? onTapDown;
|
||||
|
||||
final GestureLongPressStartCallback? onLongPressStart;
|
||||
final GestureLongPressEndCallback? onLongPressEnd;
|
||||
|
||||
final Widget? child;
|
||||
|
||||
final HitTestBehavior? behavior;
|
||||
|
@ -63,7 +68,7 @@ class PhotoViewGestureDetector extends StatelessWidget {
|
|||
}
|
||||
|
||||
if (onDragStart != null || onDragEnd != null || onDragUpdate != null) {
|
||||
gestures[VerticalDragGestureRecognizer] =
|
||||
gestures[VerticalDragGestureRecognizer] =
|
||||
GestureRecognizerFactoryWithHandlers<VerticalDragGestureRecognizer>(
|
||||
() => VerticalDragGestureRecognizer(debugOwner: this),
|
||||
(VerticalDragGestureRecognizer instance) {
|
||||
|
@ -75,6 +80,18 @@ class PhotoViewGestureDetector extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
|
||||
if (onLongPressStart != null || onLongPressEnd != null) {
|
||||
gestures[LongPressGestureRecognizer] =
|
||||
GestureRecognizerFactoryWithHandlers<LongPressGestureRecognizer>(
|
||||
() => LongPressGestureRecognizer(debugOwner: this),
|
||||
(LongPressGestureRecognizer instance) {
|
||||
instance
|
||||
..onLongPressStart = onLongPressStart
|
||||
..onLongPressEnd = onLongPressEnd;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
gestures[DoubleTapGestureRecognizer] =
|
||||
GestureRecognizerFactoryWithHandlers<DoubleTapGestureRecognizer>(
|
||||
() => DoubleTapGestureRecognizer(debugOwner: this),
|
||||
|
@ -236,7 +253,7 @@ class PhotoViewGestureRecognizer extends ScaleGestureRecognizer {
|
|||
/// ```
|
||||
class PhotoViewGestureDetectorScope extends InheritedWidget {
|
||||
const PhotoViewGestureDetectorScope({
|
||||
super.key,
|
||||
super.key,
|
||||
this.axis,
|
||||
this.touchSlopFactor = .2,
|
||||
required Widget child,
|
||||
|
@ -254,7 +271,7 @@ class PhotoViewGestureDetectorScope extends InheritedWidget {
|
|||
// 0: most reactive but will not let tap recognizers accept gestures
|
||||
// <1: less reactive but gives the most leeway to other recognizers
|
||||
// 1: will not be able to compete with a `HorizontalDragGestureRecognizer` up the widget tree
|
||||
final double touchSlopFactor;
|
||||
final double touchSlopFactor;
|
||||
|
||||
@override
|
||||
bool updateShouldNotify(PhotoViewGestureDetectorScope oldWidget) {
|
||||
|
|
|
@ -27,6 +27,8 @@ class ImageWrapper extends StatefulWidget {
|
|||
required this.onDragStart,
|
||||
required this.onDragEnd,
|
||||
required this.onDragUpdate,
|
||||
required this.onLongPressStart,
|
||||
required this.onLongPressEnd,
|
||||
required this.onScaleEnd,
|
||||
required this.outerSize,
|
||||
required this.gestureDetectorBehavior,
|
||||
|
@ -57,6 +59,8 @@ class ImageWrapper extends StatefulWidget {
|
|||
final PhotoViewImageDragStartCallback? onDragStart;
|
||||
final PhotoViewImageDragEndCallback? onDragEnd;
|
||||
final PhotoViewImageDragUpdateCallback? onDragUpdate;
|
||||
final PhotoViewImageLongPressStartCallback? onLongPressStart;
|
||||
final PhotoViewImageLongPressEndCallback? onLongPressEnd;
|
||||
final PhotoViewImageScaleEndCallback? onScaleEnd;
|
||||
final Size outerSize;
|
||||
final HitTestBehavior? gestureDetectorBehavior;
|
||||
|
@ -201,6 +205,8 @@ class _ImageWrapperState extends State<ImageWrapper> {
|
|||
onDragStart: widget.onDragStart,
|
||||
onDragEnd: widget.onDragEnd,
|
||||
onDragUpdate: widget.onDragUpdate,
|
||||
onLongPressStart: widget.onLongPressStart,
|
||||
onLongPressEnd: widget.onLongPressEnd,
|
||||
onScaleEnd: widget.onScaleEnd,
|
||||
gestureDetectorBehavior: widget.gestureDetectorBehavior,
|
||||
tightMode: widget.tightMode ?? false,
|
||||
|
@ -253,6 +259,8 @@ class CustomChildWrapper extends StatelessWidget {
|
|||
this.onDragStart,
|
||||
this.onDragEnd,
|
||||
this.onDragUpdate,
|
||||
this.onLongPressStart,
|
||||
this.onLongPressEnd,
|
||||
this.onScaleEnd,
|
||||
required this.outerSize,
|
||||
this.gestureDetectorBehavior,
|
||||
|
@ -283,6 +291,8 @@ class CustomChildWrapper extends StatelessWidget {
|
|||
final PhotoViewImageDragStartCallback? onDragStart;
|
||||
final PhotoViewImageDragEndCallback? onDragEnd;
|
||||
final PhotoViewImageDragUpdateCallback? onDragUpdate;
|
||||
final PhotoViewImageLongPressStartCallback? onLongPressStart;
|
||||
final PhotoViewImageLongPressEndCallback? onLongPressEnd;
|
||||
final PhotoViewImageScaleEndCallback? onScaleEnd;
|
||||
final Size outerSize;
|
||||
final HitTestBehavior? gestureDetectorBehavior;
|
||||
|
@ -316,6 +326,8 @@ class CustomChildWrapper extends StatelessWidget {
|
|||
onDragStart: onDragStart,
|
||||
onDragEnd: onDragEnd,
|
||||
onDragUpdate: onDragUpdate,
|
||||
onLongPressEnd: onLongPressEnd,
|
||||
onLongPressStart: onLongPressStart,
|
||||
onScaleEnd: onScaleEnd,
|
||||
gestureDetectorBehavior: gestureDetectorBehavior,
|
||||
tightMode: tightMode ?? false,
|
||||
|
|
Loading…
Reference in a new issue