Skip to content

Commit 361cc02

Browse files
committed
lightbox: Allow zooming in with video lightbox.
Fixes zulip#1287
1 parent e932a05 commit 361cc02

File tree

2 files changed

+49
-13
lines changed

2 files changed

+49
-13
lines changed

lib/widgets/lightbox.dart

+16-13
Original file line numberDiff line numberDiff line change
@@ -549,19 +549,22 @@ class _VideoLightboxPageState extends State<VideoLightboxPage> with PerAccountSt
549549
message: widget.message,
550550
buildAppBarBottom: (context) => null,
551551
buildBottomAppBar: _buildBottomAppBar,
552-
child: SafeArea(
553-
child: Center(
554-
child: Stack(alignment: Alignment.center, children: [
555-
if (_controller != null && _controller!.value.isInitialized)
556-
AspectRatio(
557-
aspectRatio: _controller!.value.aspectRatio,
558-
child: VideoPlayer(_controller!)),
559-
if (_controller == null || !_controller!.value.isInitialized || _controller!.value.isBuffering)
560-
const SizedBox(
561-
width: 32,
562-
height: 32,
563-
child: CircularProgressIndicator(color: Colors.white)),
564-
]))));
552+
child: Stack(alignment: Alignment.center, children: [
553+
InteractiveViewer(
554+
child: SafeArea(
555+
child: Center(
556+
child: (_controller != null && _controller!.value.isInitialized)
557+
? AspectRatio(
558+
aspectRatio: _controller!.value.aspectRatio,
559+
child: VideoPlayer(_controller!))
560+
: Container()))
561+
),
562+
if (_controller == null || !_controller!.value.isInitialized || _controller!.value.isBuffering)
563+
const SizedBox(
564+
width: 32,
565+
height: 32,
566+
child: CircularProgressIndicator(color: Colors.white)),
567+
]));
565568
}
566569
}
567570

test/widgets/lightbox_test.dart

+33
Original file line numberDiff line numberDiff line change
@@ -557,5 +557,38 @@ void main() {
557557
check(position).isGreaterThan(basePosition);
558558
check(platform.position).equals(position);
559559
});
560+
561+
testWidgets('video can be zoomed in and out', (tester) async {
562+
await setupPage(tester, videoSrc: Uri.parse(kTestVideoUrl));
563+
check(platform.isPlaying).isTrue();
564+
565+
final initialRect = tester.getRect(find.byType(VideoPlayer));
566+
final bottomRight = initialRect.bottomRight;
567+
// Define initial positions for two fingers near bottom right corner:
568+
// In the case of mismatch between media and device orientation,
569+
// the zoom gesture is still expected to work,
570+
// even if the fingers are not in the image's frame.
571+
final Offset finger1Start = bottomRight + const Offset(-70.0, -70.0);
572+
final Offset finger2Start = bottomRight + const Offset(-20.0, -20.0);
573+
final TestGesture gesture1 = await tester.startGesture(finger1Start);
574+
final TestGesture gesture2 = await tester.startGesture(finger2Start);
575+
await tester.pump();
576+
577+
// Simulate pinch out (zoom in)
578+
await gesture1.moveBy(const Offset(-20.0, -20.0));
579+
await gesture2.moveBy(const Offset(20.0, 20.0));
580+
await tester.pump();
581+
final zoomedInRect = tester.getRect(find.byType(VideoPlayer));
582+
check(zoomedInRect.width).isGreaterThan(initialRect.width);
583+
check(zoomedInRect.height).isGreaterThan(initialRect.height);
584+
585+
// Simulate pinch out (zoom in)
586+
await gesture1.moveBy(const Offset(30.0, 30.0));
587+
await gesture2.moveBy(const Offset(-30.0, -30.0));
588+
await tester.pump();
589+
final zoomedOutRect = tester.getRect(find.byType(VideoPlayer));
590+
check(zoomedOutRect.width).isLessThan(zoomedInRect.width);
591+
check(zoomedOutRect.height).isLessThan(zoomedInRect.height);
592+
});
560593
});
561594
}

0 commit comments

Comments
 (0)