From 9570d43e433c1d6b5623c75fe9150a750a9788e6 Mon Sep 17 00:00:00 2001 From: Tommy Chow Date: Tue, 27 Dec 2022 23:47:55 -0500 Subject: [PATCH] Add auto PiP on Android and redesign stream overlay (#218) * Improve PiP behavior (Android) Added the ability to enter PiP mode when leaving the app on Android. * Add automatic PiP option * Redesign video overlay * Update stream card uptime counter * Use gradient for overlay opacity * Restore play button when paused on iOS * Restore refresh button on overlay * Prefer above for category tooltip * Increase default overlay opacity to 80% * Improve pip behavior * Fix uptime setState after dispose * Remove automatic pip option Redundant since you can disable it in system settings * Check if `setAutoEnterEnabled` is available * Fix missing pip auto enter * Disable auto pip when leaving channel * Fix pip exception on iOS --- .../com/tommychow/frosty/MainActivity.kt | 4 +- lib/screens/channel/channel.dart | 28 ++- lib/screens/channel/video/video.dart | 39 ++- lib/screens/channel/video/video_overlay.dart | 226 +++++++++++------- lib/screens/channel/video/video_store.dart | 27 ++- lib/screens/home/stream_list/stream_card.dart | 25 +- .../settings/stores/settings_store.dart | 2 +- .../settings/stores/settings_store.g.dart | 2 +- lib/widgets/uptime.dart | 44 ++++ pubspec.lock | 16 +- pubspec.yaml | 4 +- 11 files changed, 288 insertions(+), 129 deletions(-) create mode 100644 lib/widgets/uptime.dart diff --git a/android/app/src/main/kotlin/com/tommychow/frosty/MainActivity.kt b/android/app/src/main/kotlin/com/tommychow/frosty/MainActivity.kt index 85e2032f..a7791025 100644 --- a/android/app/src/main/kotlin/com/tommychow/frosty/MainActivity.kt +++ b/android/app/src/main/kotlin/com/tommychow/frosty/MainActivity.kt @@ -1,6 +1,6 @@ package com.tommychow.frosty -import io.flutter.embedding.android.FlutterActivity +import cl.puntito.simple_pip_mode.PipCallbackHelperActivityWrapper -class MainActivity: FlutterActivity() { +class MainActivity: PipCallbackHelperActivityWrapper() { } diff --git a/lib/screens/channel/channel.dart b/lib/screens/channel/channel.dart index 73233d1d..5b9b7915 100644 --- a/lib/screens/channel/channel.dart +++ b/lib/screens/channel/channel.dart @@ -1,6 +1,5 @@ import 'dart:io'; -import 'package:floating/floating.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; @@ -22,6 +21,8 @@ import 'package:frosty/screens/settings/stores/auth_store.dart'; import 'package:frosty/screens/settings/stores/settings_store.dart'; import 'package:frosty/widgets/modal.dart'; import 'package:provider/provider.dart'; +import 'package:simple_pip_mode/actions/pip_actions_layout.dart'; +import 'package:simple_pip_mode/pip_widget.dart'; /// Creates a widget that shows the video stream (if live) and chat of the given user. class VideoChat extends StatefulWidget { @@ -133,8 +134,20 @@ class _VideoChatState extends State { return AnimatedOpacity( opacity: _videoStore.overlayVisible ? 1.0 : 0.0, duration: const Duration(milliseconds: 200), - child: ColoredBox( - color: Colors.black.withOpacity(settingsStore.overlayOpacity), + child: Container( + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + stops: const [0.0, 0.25, 0.75, 1.0], + colors: [ + Colors.black.withOpacity(settingsStore.overlayOpacity), + Colors.transparent, + Colors.transparent, + Colors.black.withOpacity(settingsStore.overlayOpacity), + ], + ), + ), child: IgnorePointer( ignoring: !_videoStore.overlayVisible, child: videoOverlay, @@ -246,10 +259,11 @@ class _VideoChatState extends State { // If on Android, use PiPSwitcher to enable PiP functionality. if (Platform.isAndroid) { - return PiPSwitcher( - floating: _videoStore.floating, - childWhenEnabled: player, - childWhenDisabled: videoChat, + return PipWidget( + pipLayout: PipActionsLayout.media_only_pause, + onPipAction: (_) => _videoStore.handlePausePlay(), + pipChild: player, + child: videoChat, ); } diff --git a/lib/screens/channel/video/video.dart b/lib/screens/channel/video/video.dart index 137d2a04..34998abf 100644 --- a/lib/screens/channel/video/video.dart +++ b/lib/screens/channel/video/video.dart @@ -1,9 +1,12 @@ +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:frosty/screens/channel/video/video_store.dart'; +import 'package:simple_pip_mode/simple_pip.dart'; import 'package:webview_flutter/webview_flutter.dart'; /// Creates a [WebView] widget that shows a channel's video stream. -class Video extends StatelessWidget { +class Video extends StatefulWidget { final VideoStore videoStore; const Video({ @@ -11,18 +14,42 @@ class Video extends StatelessWidget { required this.videoStore, }) : super(key: key); + @override + State