You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			159 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Dart
		
	
			
		
		
	
	
			159 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Dart
		
	
import 'package:flutter/material.dart';
 | 
						|
 | 
						|
import 'package:matrix/matrix.dart';
 | 
						|
 | 
						|
import 'package:fluffychat/l10n/l10n.dart';
 | 
						|
import 'package:fluffychat/pages/image_viewer/video_player.dart';
 | 
						|
import 'package:fluffychat/utils/platform_infos.dart';
 | 
						|
import 'package:fluffychat/widgets/hover_builder.dart';
 | 
						|
import 'package:fluffychat/widgets/mxc_image.dart';
 | 
						|
import 'image_viewer.dart';
 | 
						|
 | 
						|
class ImageViewerView extends StatelessWidget {
 | 
						|
  final ImageViewerController controller;
 | 
						|
 | 
						|
  const ImageViewerView(this.controller, {super.key});
 | 
						|
 | 
						|
  @override
 | 
						|
  Widget build(BuildContext context) {
 | 
						|
    final iconButtonStyle = IconButton.styleFrom(
 | 
						|
      backgroundColor: Colors.black.withAlpha(200),
 | 
						|
      foregroundColor: Colors.white,
 | 
						|
    );
 | 
						|
    return GestureDetector(
 | 
						|
      onTap: () => Navigator.of(context).pop(),
 | 
						|
      child: Scaffold(
 | 
						|
        backgroundColor: Colors.black.withAlpha(128),
 | 
						|
        extendBodyBehindAppBar: true,
 | 
						|
        appBar: AppBar(
 | 
						|
          elevation: 0,
 | 
						|
          leading: IconButton(
 | 
						|
            style: iconButtonStyle,
 | 
						|
            icon: const Icon(Icons.close),
 | 
						|
            onPressed: Navigator.of(context).pop,
 | 
						|
            color: Colors.white,
 | 
						|
            tooltip: L10n.of(context).close,
 | 
						|
          ),
 | 
						|
          backgroundColor: Colors.transparent,
 | 
						|
          actions: [
 | 
						|
            IconButton(
 | 
						|
              style: iconButtonStyle,
 | 
						|
              icon: const Icon(Icons.reply_outlined),
 | 
						|
              onPressed: controller.forwardAction,
 | 
						|
              color: Colors.white,
 | 
						|
              tooltip: L10n.of(context).share,
 | 
						|
            ),
 | 
						|
            const SizedBox(width: 8),
 | 
						|
            IconButton(
 | 
						|
              style: iconButtonStyle,
 | 
						|
              icon: const Icon(Icons.download_outlined),
 | 
						|
              onPressed: () => controller.saveFileAction(context),
 | 
						|
              color: Colors.white,
 | 
						|
              tooltip: L10n.of(context).downloadFile,
 | 
						|
            ),
 | 
						|
            const SizedBox(width: 8),
 | 
						|
            if (PlatformInfos.isMobile)
 | 
						|
              // Use builder context to correctly position the share dialog on iPad
 | 
						|
              Padding(
 | 
						|
                padding: const EdgeInsets.only(right: 8.0),
 | 
						|
                child: Builder(
 | 
						|
                  builder: (context) => IconButton(
 | 
						|
                    style: iconButtonStyle,
 | 
						|
                    onPressed: () => controller.shareFileAction(context),
 | 
						|
                    tooltip: L10n.of(context).share,
 | 
						|
                    color: Colors.white,
 | 
						|
                    icon: Icon(Icons.adaptive.share_outlined),
 | 
						|
                  ),
 | 
						|
                ),
 | 
						|
              ),
 | 
						|
          ],
 | 
						|
        ),
 | 
						|
        body: HoverBuilder(
 | 
						|
          builder: (context, hovered) => Stack(
 | 
						|
            children: [
 | 
						|
              KeyboardListener(
 | 
						|
                focusNode: controller.focusNode,
 | 
						|
                onKeyEvent: controller.onKeyEvent,
 | 
						|
                child: PageView.builder(
 | 
						|
                  scrollDirection: Axis.vertical,
 | 
						|
                  controller: controller.pageController,
 | 
						|
                  itemCount: controller.allEvents.length,
 | 
						|
                  itemBuilder: (context, i) {
 | 
						|
                    final event = controller.allEvents[i];
 | 
						|
                    switch (event.messageType) {
 | 
						|
                      case MessageTypes.Video:
 | 
						|
                        return Padding(
 | 
						|
                          padding: const EdgeInsets.only(top: 52.0),
 | 
						|
                          child: Center(
 | 
						|
                            child: GestureDetector(
 | 
						|
                              // Ignore taps to not go back here:
 | 
						|
                              onTap: () {},
 | 
						|
                              child: EventVideoPlayer(event),
 | 
						|
                            ),
 | 
						|
                          ),
 | 
						|
                        );
 | 
						|
                      case MessageTypes.Image:
 | 
						|
                      case MessageTypes.Sticker:
 | 
						|
                      default:
 | 
						|
                        return InteractiveViewer(
 | 
						|
                          minScale: 1.0,
 | 
						|
                          maxScale: 10.0,
 | 
						|
                          onInteractionEnd: controller.onInteractionEnds,
 | 
						|
                          child: Center(
 | 
						|
                            child: Hero(
 | 
						|
                              tag: event.eventId,
 | 
						|
                              child: GestureDetector(
 | 
						|
                                // Ignore taps to not go back here:
 | 
						|
                                onTap: () {},
 | 
						|
                                child: MxcImage(
 | 
						|
                                  key: ValueKey(event.eventId),
 | 
						|
                                  event: event,
 | 
						|
                                  fit: BoxFit.contain,
 | 
						|
                                  isThumbnail: false,
 | 
						|
                                  animated: true,
 | 
						|
                                ),
 | 
						|
                              ),
 | 
						|
                            ),
 | 
						|
                          ),
 | 
						|
                        );
 | 
						|
                    }
 | 
						|
                  },
 | 
						|
                ),
 | 
						|
              ),
 | 
						|
              if (hovered)
 | 
						|
                Align(
 | 
						|
                  alignment: Alignment.centerRight,
 | 
						|
                  child: Column(
 | 
						|
                    mainAxisSize: MainAxisSize.min,
 | 
						|
                    children: [
 | 
						|
                      if (controller.canGoBack)
 | 
						|
                        Padding(
 | 
						|
                          padding: const EdgeInsets.all(12.0),
 | 
						|
                          child: IconButton(
 | 
						|
                            style: iconButtonStyle,
 | 
						|
                            tooltip: L10n.of(context).previous,
 | 
						|
                            icon: const Icon(Icons.arrow_upward_outlined),
 | 
						|
                            onPressed: controller.prevImage,
 | 
						|
                          ),
 | 
						|
                        ),
 | 
						|
                      if (controller.canGoNext)
 | 
						|
                        Padding(
 | 
						|
                          padding: const EdgeInsets.all(12.0),
 | 
						|
                          child: IconButton(
 | 
						|
                            style: iconButtonStyle,
 | 
						|
                            tooltip: L10n.of(context).next,
 | 
						|
                            icon: const Icon(Icons.arrow_downward_outlined),
 | 
						|
                            onPressed: controller.nextImage,
 | 
						|
                          ),
 | 
						|
                        ),
 | 
						|
                    ],
 | 
						|
                  ),
 | 
						|
                ),
 | 
						|
            ],
 | 
						|
          ),
 | 
						|
        ),
 | 
						|
      ),
 | 
						|
    );
 | 
						|
  }
 | 
						|
}
 |