diff --git a/lib/app/app_navigator.dart b/lib/app/app_navigator.dart index aeb19e0b0..002d63b0e 100644 --- a/lib/app/app_navigator.dart +++ b/lib/app/app_navigator.dart @@ -199,15 +199,27 @@ class AppChatPageRoute extends PageRoute if (AppMotion.isReduced(context) && !_fullPageBackSwipeActive) { return child; } - final leaving = _fullPageBackSwipeActive; + final leaving = + _fullPageBackSwipeActive || + animation.status == AnimationStatus.reverse || + animation.status == AnimationStatus.dismissed; if (leaving) { final effectiveAnimation = popGestureInProgress ? animation : CurvedAnimation( parent: animation, curve: AppMotion.standard, - reverseCurve: AppMotion.accelerate, + reverseCurve: AppMotion.standard.flipped, ); + final slide = SlideTransition( + position: Tween( + begin: const Offset(1, 0), + end: Offset.zero, + ).animate(effectiveAnimation), + transformHitTests: false, + child: child, + ); + if (!_fullPageBackSwipeActive) return slide; return Stack( fit: StackFit.expand, children: [ @@ -220,14 +232,7 @@ class AppChatPageRoute extends PageRoute child: ColoredBox(color: Color(0xFF000000)), ), ), - SlideTransition( - position: Tween( - begin: const Offset(1, 0), - end: Offset.zero, - ).animate(effectiveAnimation), - transformHitTests: false, - child: child, - ), + slide, ], ); } diff --git a/test/full_page_back_swipe_test.dart b/test/full_page_back_swipe_test.dart index 24db3ee9a..2160d1d6a 100644 --- a/test/full_page_back_swipe_test.dart +++ b/test/full_page_back_swipe_test.dart @@ -392,7 +392,7 @@ void main() { expect(tester.takeException(), isNull); }); - testWidgets('ordinary pop keeps the compact non-interactive transition', ( + testWidgets('ordinary pop slides the conversation across the full viewport', ( tester, ) async { final harness = await _pumpRouteHarness(tester); @@ -402,8 +402,14 @@ void main() { await tester.pump(const Duration(milliseconds: 90)); final chatLeft = tester.getTopLeft(find.byKey(_chatKey)).dx; - expect(chatLeft, greaterThan(0)); - expect(chatLeft, lessThan(30)); + expect(chatLeft, greaterThan(180)); + expect(chatLeft, lessThan(390)); + final revealedColor = await _pixelAt( + tester, + harness, + const Offset(24, 420), + ); + _expectColorClose(revealedColor, _previousColor); await tester.pumpAndSettle(); expect(harness.observer.popCount, 1); diff --git a/test/main_tab_motion_test.dart b/test/main_tab_motion_test.dart index 5782c3dc3..7e143128b 100644 --- a/test/main_tab_motion_test.dart +++ b/test/main_tab_motion_test.dart @@ -19,6 +19,7 @@ import 'package:mithka/chat/chat_view.dart'; import 'package:mithka/chats/archived_chats_view.dart'; import 'package:mithka/chats/chat_list_view.dart'; import 'package:mithka/chats/search_view.dart'; +import 'package:mithka/components/app_icons.dart'; import 'package:mithka/components/drawer_controller.dart' as dc; import 'package:mithka/contacts/contacts_view.dart'; import 'package:mithka/l10n/app_locale_controller.dart'; @@ -598,6 +599,51 @@ void main() { debugDefaultTargetPlatformOverride = null; } }); + + testWidgets( + 'phone chat back button slides the conversation out across the viewport', + (tester) async { + debugDefaultTargetPlatformOverride = TargetPlatform.iOS; + try { + await _setSurfaceSize(tester, const Size(390, 844)); + await _pumpMainShell(tester); + final deepLinks = ChatDeepLinkController.shared; + + deepLinks.openChat(chatId: 41, title: 'Mobile chat', messageId: 410); + await tester.pump(); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 350)); + _discardMissingTdlibErrors(tester); + + final chatView = find.byType(ChatView); + expect(chatView, findsOneWidget); + expect(tester.getTopLeft(chatView).dx, closeTo(0, 0.5)); + + final backButton = find.descendant( + of: chatView, + matching: find.byIcon(HeroAppIcons.chevronLeft.data), + ); + expect(backButton, findsOneWidget); + await tester.tap(backButton); + await tester.pump(); + await tester.pump(const Duration(milliseconds: 90)); + _discardMissingTdlibErrors(tester); + + final midPopLeft = tester.getTopLeft(chatView).dx; + expect(midPopLeft, greaterThan(180)); + expect(midPopLeft, lessThan(390)); + + await tester.pump(const Duration(milliseconds: 240)); + await tester.pump(); + _discardMissingTdlibErrors(tester); + expect(chatView, findsNothing); + expect(find.byType(ChatListView), findsOneWidget); + await _disposeShell(tester); + } finally { + debugDefaultTargetPlatformOverride = null; + } + }, + ); } void _discardMissingTdlibErrors(WidgetTester tester) {