// SPDX-FileCopyrightText: 2019-Present Christian Kußowski // SPDX-FileCopyrightText: 2019-Present Contributors to FluffyChat // // SPDX-License-Identifier: AGPL-3.0-or-later import 'package:tatchat/l10n/l10n.dart'; import 'package:material_ui/material_ui.dart'; import 'mxc_image.dart'; class MxcImageViewer extends StatelessWidget { final Uri mxContent; const MxcImageViewer(this.mxContent, {super.key}); /// The viewer is opened with `showDialog` on the root navigator, so closing /// it must always target the root navigator. static void _close(BuildContext context) => Navigator.of(context, rootNavigator: true).pop(); @override Widget build(BuildContext context) { final iconButtonStyle = IconButton.styleFrom( backgroundColor: Colors.black.withAlpha(200), foregroundColor: Colors.white, ); return BackButtonListener( // Same reason as the room image viewer: this dialog lives on the root // navigator, but go_router asks the shell navigator first, so only a // [BackButtonListener] (which runs before the router) can keep the back // button from popping the page underneath. onBackButtonPressed: () async { _close(context); return true; }, child: PopScope( canPop: false, onPopInvokedWithResult: (didPop, _) { if (didPop) return; _close(context); }, child: GestureDetector( onTap: () => _close(context), child: Scaffold( backgroundColor: Colors.black.withAlpha(128), extendBodyBehindAppBar: true, appBar: AppBar( elevation: 0, leading: IconButton( style: iconButtonStyle, icon: const Icon(Icons.close), onPressed: () => _close(context), color: Colors.white, tooltip: L10n.of(context).close, ), backgroundColor: Colors.transparent, ), body: InteractiveViewer( minScale: 1.0, maxScale: 10.0, onInteractionEnd: (endDetails) { if (endDetails.velocity.pixelsPerSecond.dy > MediaQuery.sizeOf(context).height * 1.5) { _close(context); } }, child: Center( child: GestureDetector( // Ignore taps to not go back here: onTap: () {}, child: MxcImage( key: ValueKey(mxContent.toString()), uri: mxContent, fit: BoxFit.contain, isThumbnail: false, animated: true, ), ), ), ), ), ), ), ); } }