This commit is contained in:
		@@ -16,9 +16,6 @@ class FullScreenMediaView extends StatefulWidget {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class _FullScreenMediaViewState extends State<FullScreenMediaView> {
 | 
					class _FullScreenMediaViewState extends State<FullScreenMediaView> {
 | 
				
			||||||
  double _dragOffset = 0.0;
 | 
					 | 
				
			||||||
  int _pointerCount = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  void initState() {
 | 
					  void initState() {
 | 
				
			||||||
    super.initState();
 | 
					    super.initState();
 | 
				
			||||||
@@ -33,68 +30,44 @@ class _FullScreenMediaViewState extends State<FullScreenMediaView> {
 | 
				
			|||||||
    super.dispose();
 | 
					    super.dispose();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  void _onVerticalDragUpdate(DragUpdateDetails details) {
 | 
					 | 
				
			||||||
    if (_pointerCount != 1) return;
 | 
					 | 
				
			||||||
    setState(() => _dragOffset += details.delta.dy);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  void _onVerticalDragEnd(DragEndDetails details) {
 | 
					 | 
				
			||||||
    if (_dragOffset < -100 || _dragOffset > 100) {
 | 
					 | 
				
			||||||
      Navigator.of(context).pop();
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      setState(() => _dragOffset = 0.0);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  Widget build(BuildContext context) {
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
    return Scaffold(
 | 
					    return Scaffold(
 | 
				
			||||||
      backgroundColor: Colors.black,
 | 
					      backgroundColor: Colors.black,
 | 
				
			||||||
      body: Listener(
 | 
					      body: Stack(
 | 
				
			||||||
        onPointerDown: (_) {
 | 
					        children: [
 | 
				
			||||||
          setState(() => _pointerCount++);
 | 
					          Positioned.fill(
 | 
				
			||||||
        },
 | 
					            child: widget.item.mime.startsWith('image')
 | 
				
			||||||
        onPointerUp: (_) {
 | 
					                ? InteractiveViewer(
 | 
				
			||||||
          setState(() => _pointerCount = (_pointerCount - 1).clamp(0, 10));
 | 
					                    minScale: 1.0,
 | 
				
			||||||
        },
 | 
					                    maxScale: 6.0,
 | 
				
			||||||
        child: GestureDetector(
 | 
					                    child: CachedNetworkImage(
 | 
				
			||||||
          behavior: HitTestBehavior.opaque,
 | 
					                      imageUrl: widget.item.mediaUrl,
 | 
				
			||||||
          onVerticalDragUpdate: _onVerticalDragUpdate,
 | 
					                      fit: BoxFit.contain,
 | 
				
			||||||
          onVerticalDragEnd: _onVerticalDragEnd,
 | 
					                      placeholder: (context, url) =>
 | 
				
			||||||
          child: Transform.translate(
 | 
					                          const Center(child: CircularProgressIndicator()),
 | 
				
			||||||
            offset: Offset(0, _dragOffset),
 | 
					                      errorWidget: (context, url, error) =>
 | 
				
			||||||
            child: Stack(
 | 
					                          const Icon(Icons.error),
 | 
				
			||||||
              children: [
 | 
					                    ),
 | 
				
			||||||
                Center(
 | 
					                  )
 | 
				
			||||||
                  child: widget.item.mime.startsWith('image')
 | 
					                : SizedBox.expand(
 | 
				
			||||||
                      ? InteractiveViewer(
 | 
					                    child: VideoWidget(
 | 
				
			||||||
                          minScale: 1.0,
 | 
					                      details: widget.item,
 | 
				
			||||||
                          maxScale: 4.0,
 | 
					                      isActive: true,
 | 
				
			||||||
                          child: CachedNetworkImage(
 | 
					                      fullScreen: true,
 | 
				
			||||||
                            imageUrl: widget.item.mediaUrl,
 | 
					 | 
				
			||||||
                            fit: BoxFit.contain,
 | 
					 | 
				
			||||||
                            placeholder: (context, url) => const Center(
 | 
					 | 
				
			||||||
                              child: CircularProgressIndicator(),
 | 
					 | 
				
			||||||
                            ),
 | 
					 | 
				
			||||||
                            errorWidget: (context, url, error) =>
 | 
					 | 
				
			||||||
                                const Icon(Icons.error, color: Colors.white),
 | 
					 | 
				
			||||||
                          ),
 | 
					 | 
				
			||||||
                        )
 | 
					 | 
				
			||||||
                      : VideoWidget(details: widget.item, isActive: true),
 | 
					 | 
				
			||||||
                ),
 | 
					 | 
				
			||||||
                SafeArea(
 | 
					 | 
				
			||||||
                  child: Align(
 | 
					 | 
				
			||||||
                    alignment: Alignment.topLeft,
 | 
					 | 
				
			||||||
                    child: IconButton(
 | 
					 | 
				
			||||||
                      icon: const Icon(Icons.arrow_back, color: Colors.white),
 | 
					 | 
				
			||||||
                      onPressed: () => Navigator.of(context).pop(),
 | 
					 | 
				
			||||||
                    ),
 | 
					                    ),
 | 
				
			||||||
                  ),
 | 
					                  ),
 | 
				
			||||||
                ),
 | 
					          ),
 | 
				
			||||||
              ],
 | 
					          SafeArea(
 | 
				
			||||||
 | 
					            child: Align(
 | 
				
			||||||
 | 
					              alignment: Alignment.topLeft,
 | 
				
			||||||
 | 
					              child: IconButton(
 | 
				
			||||||
 | 
					                icon: const Icon(Icons.arrow_back),
 | 
				
			||||||
 | 
					                onPressed: () => Navigator.of(context).pop(),
 | 
				
			||||||
 | 
					              ),
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
        ),
 | 
					        ],
 | 
				
			||||||
      ),
 | 
					      ),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,8 +13,14 @@ import 'package:f0ckapp/providers/media_provider.dart';
 | 
				
			|||||||
class VideoWidget extends ConsumerStatefulWidget {
 | 
					class VideoWidget extends ConsumerStatefulWidget {
 | 
				
			||||||
  final MediaItem details;
 | 
					  final MediaItem details;
 | 
				
			||||||
  final bool isActive;
 | 
					  final bool isActive;
 | 
				
			||||||
 | 
					  final bool fullScreen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const VideoWidget({super.key, required this.details, required this.isActive});
 | 
					  const VideoWidget({
 | 
				
			||||||
 | 
					    super.key,
 | 
				
			||||||
 | 
					    required this.details,
 | 
				
			||||||
 | 
					    required this.isActive,
 | 
				
			||||||
 | 
					    this.fullScreen = false,
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override
 | 
					  @override
 | 
				
			||||||
  ConsumerState<VideoWidget> createState() => _VideoWidgetState();
 | 
					  ConsumerState<VideoWidget> createState() => _VideoWidgetState();
 | 
				
			||||||
@@ -90,17 +96,15 @@ class _VideoWidgetState extends ConsumerState<VideoWidget> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    bool isAudio = widget.details.mime.startsWith('audio');
 | 
					    bool isAudio = widget.details.mime.startsWith('audio');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return Column(
 | 
					    if (widget.fullScreen) {
 | 
				
			||||||
      mainAxisSize: MainAxisSize.min,
 | 
					      return Stack(
 | 
				
			||||||
      children: [
 | 
					        children: [
 | 
				
			||||||
        AspectRatio(
 | 
					          Center(
 | 
				
			||||||
          aspectRatio: _controller.value.isInitialized
 | 
					            child: AspectRatio(
 | 
				
			||||||
              ? _controller.value.aspectRatio
 | 
					              aspectRatio: _controller.value.isInitialized
 | 
				
			||||||
              : 9 / 16,
 | 
					                  ? _controller.value.aspectRatio
 | 
				
			||||||
          child: Stack(
 | 
					                  : 9 / 16,
 | 
				
			||||||
            alignment: Alignment.topCenter,
 | 
					              child: GestureDetector(
 | 
				
			||||||
            children: [
 | 
					 | 
				
			||||||
              GestureDetector(
 | 
					 | 
				
			||||||
                onTap: _onTap,
 | 
					                onTap: _onTap,
 | 
				
			||||||
                child: isAudio
 | 
					                child: isAudio
 | 
				
			||||||
                    ? CachedNetworkImage(
 | 
					                    ? CachedNetworkImage(
 | 
				
			||||||
@@ -118,24 +122,71 @@ class _VideoWidgetState extends ConsumerState<VideoWidget> {
 | 
				
			|||||||
                    ? CachedVideoPlayerPlus(_controller)
 | 
					                    ? CachedVideoPlayerPlus(_controller)
 | 
				
			||||||
                    : const Center(child: CircularProgressIndicator()),
 | 
					                    : const Center(child: CircularProgressIndicator()),
 | 
				
			||||||
              ),
 | 
					              ),
 | 
				
			||||||
              if (_controller.value.isInitialized && _showControls) ...[
 | 
					            ),
 | 
				
			||||||
                IgnorePointer(
 | 
					          ),
 | 
				
			||||||
                  ignoring: true,
 | 
					          if (_controller.value.isInitialized && _showControls)
 | 
				
			||||||
                  child: Container(
 | 
					            Positioned.fill(
 | 
				
			||||||
                    color: Colors.black.withValues(alpha: 0.5),
 | 
					              child: GestureDetector(
 | 
				
			||||||
                    width: double.infinity,
 | 
					                onTap: _onTap,
 | 
				
			||||||
                    height: double.infinity,
 | 
					                child: Container(
 | 
				
			||||||
 | 
					                  color: Colors.black.withValues(alpha: 0.5),
 | 
				
			||||||
 | 
					                  child: VideoControlsOverlay(
 | 
				
			||||||
 | 
					                    controller: _controller,
 | 
				
			||||||
 | 
					                    button: () => _onTap(ctrlButton: true),
 | 
				
			||||||
                  ),
 | 
					                  ),
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                VideoControlsOverlay(
 | 
					              ),
 | 
				
			||||||
                  controller: _controller,
 | 
					            ),
 | 
				
			||||||
                  button: () => _onTap(ctrlButton: true),
 | 
					        ],
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      return Column(
 | 
				
			||||||
 | 
					        mainAxisSize: MainAxisSize.min,
 | 
				
			||||||
 | 
					        children: [
 | 
				
			||||||
 | 
					          AspectRatio(
 | 
				
			||||||
 | 
					            aspectRatio: _controller.value.isInitialized
 | 
				
			||||||
 | 
					                ? _controller.value.aspectRatio
 | 
				
			||||||
 | 
					                : 9 / 16,
 | 
				
			||||||
 | 
					            child: Stack(
 | 
				
			||||||
 | 
					              alignment: Alignment.topCenter,
 | 
				
			||||||
 | 
					              children: [
 | 
				
			||||||
 | 
					                GestureDetector(
 | 
				
			||||||
 | 
					                  onTap: _onTap,
 | 
				
			||||||
 | 
					                  child: isAudio
 | 
				
			||||||
 | 
					                      ? CachedNetworkImage(
 | 
				
			||||||
 | 
					                          imageUrl: widget.details.coverUrl,
 | 
				
			||||||
 | 
					                          fit: BoxFit.cover,
 | 
				
			||||||
 | 
					                          placeholder: (context, url) =>
 | 
				
			||||||
 | 
					                              const CircularProgressIndicator(),
 | 
				
			||||||
 | 
					                          errorWidget: (context, url, error) => Image.asset(
 | 
				
			||||||
 | 
					                            'assets/images/music.webp',
 | 
				
			||||||
 | 
					                            fit: BoxFit.contain,
 | 
				
			||||||
 | 
					                            width: double.infinity,
 | 
				
			||||||
 | 
					                          ),
 | 
				
			||||||
 | 
					                        )
 | 
				
			||||||
 | 
					                      : _controller.value.isInitialized
 | 
				
			||||||
 | 
					                      ? CachedVideoPlayerPlus(_controller)
 | 
				
			||||||
 | 
					                      : const Center(child: CircularProgressIndicator()),
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
 | 
					                if (_controller.value.isInitialized && _showControls) ...[
 | 
				
			||||||
 | 
					                  IgnorePointer(
 | 
				
			||||||
 | 
					                    ignoring: true,
 | 
				
			||||||
 | 
					                    child: Container(
 | 
				
			||||||
 | 
					                      color: Colors.black.withValues(alpha: 0.5),
 | 
				
			||||||
 | 
					                      width: double.infinity,
 | 
				
			||||||
 | 
					                      height: double.infinity,
 | 
				
			||||||
 | 
					                    ),
 | 
				
			||||||
 | 
					                  ),
 | 
				
			||||||
 | 
					                  VideoControlsOverlay(
 | 
				
			||||||
 | 
					                    controller: _controller,
 | 
				
			||||||
 | 
					                    button: () => _onTap(ctrlButton: true),
 | 
				
			||||||
 | 
					                  ),
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
              ],
 | 
					              ],
 | 
				
			||||||
            ],
 | 
					            ),
 | 
				
			||||||
          ),
 | 
					          ),
 | 
				
			||||||
        ),
 | 
					        ],
 | 
				
			||||||
      ],
 | 
					      );
 | 
				
			||||||
    );
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
name: f0ckapp
 | 
					name: f0ckapp
 | 
				
			||||||
description: "A new Flutter project."
 | 
					description: "f0ck schm0ck"
 | 
				
			||||||
# The following line prevents the package from being accidentally published to
 | 
					# The following line prevents the package from being accidentally published to
 | 
				
			||||||
# pub.dev using `flutter pub publish`. This is preferred for private packages.
 | 
					# pub.dev using `flutter pub publish`. This is preferred for private packages.
 | 
				
			||||||
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
 | 
					publish_to: 'none' # Remove this line if you wish to publish to pub.dev
 | 
				
			||||||
@@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
 | 
				
			|||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
 | 
					# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
 | 
				
			||||||
# In Windows, build-name is used as the major, minor, and patch parts
 | 
					# In Windows, build-name is used as the major, minor, and patch parts
 | 
				
			||||||
# of the product and file versions while build-number is used as the build suffix.
 | 
					# of the product and file versions while build-number is used as the build suffix.
 | 
				
			||||||
version: 1.1.18+48
 | 
					version: 1.1.19+49
 | 
				
			||||||
 | 
					
 | 
				
			||||||
environment:
 | 
					environment:
 | 
				
			||||||
  sdk: ^3.9.0-100.2.beta
 | 
					  sdk: ^3.9.0-100.2.beta
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user