Revise video/chat screen

- Added video overlay with controls for a cleaner look
- Added app bar when video is disabled
- Removed bottom back button in favor of a back button on the overlay
This commit is contained in:
tommyxchow 2021-11-11 23:00:32 -05:00
parent e31c065864
commit bbd810b0c5
4 changed files with 121 additions and 31 deletions

View file

@ -1,17 +1,20 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:frosty/screens/settings.dart';
import 'package:frosty/stores/auth_store.dart';
import 'package:frosty/stores/chat_store.dart';
import 'package:frosty/stores/settings_store.dart';
import 'package:frosty/stores/video_store.dart';
import 'package:frosty/widgets/chat.dart';
import 'package:frosty/widgets/video.dart';
import 'package:provider/provider.dart';
class VideoChat extends StatelessWidget {
final String userLogin;
final String userName;
const VideoChat({Key? key, required this.userLogin}) : super(key: key);
const VideoChat({Key? key, required this.userLogin, required this.userName}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -21,17 +24,41 @@ class VideoChat extends StatelessWidget {
children: [
Observer(
builder: (_) {
return Visibility(
visible: context.read<SettingsStore>().videoEnabled,
child: AspectRatio(
if (context.read<SettingsStore>().videoEnabled) {
return AspectRatio(
aspectRatio: 16 / 9,
child: Video(channelName: userLogin),
),
child: Video(
channelName: userLogin,
videoStore: VideoStore(),
settingsStore: context.read<SettingsStore>(),
),
);
}
return AppBar(
title: Text(userName),
actions: [
IconButton(
icon: const Icon(Icons.settings),
onPressed: () {
showModalBottomSheet(
context: context,
builder: (context) {
return Settings(settingsStore: context.read<SettingsStore>());
},
);
},
),
],
);
},
),
Expanded(
child: Chat(chatStore: ChatStore(auth: context.read<AuthStore>(), channelName: userLogin)),
child: Chat(
chatStore: ChatStore(
auth: context.read<AuthStore>(),
channelName: userLogin,
),
),
),
],
),

View file

@ -1,4 +1,3 @@
import 'package:flutter/foundation.dart';
import 'package:mobx/mobx.dart';
import 'package:shared_preferences/shared_preferences.dart';

View file

@ -1,9 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:frosty/screens/settings.dart';
import 'package:frosty/stores/auth_store.dart';
import 'package:frosty/stores/chat_store.dart';
import 'package:frosty/stores/settings_store.dart';
import 'package:frosty/widgets/chat_stats.dart';
import 'package:provider/provider.dart';
@ -63,21 +61,6 @@ class _ChatState extends State<Chat> {
),
Row(
children: [
IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () => Navigator.of(context).pop(),
),
IconButton(
icon: const Icon(Icons.settings),
onPressed: () {
showModalBottomSheet(
context: context,
builder: (context) {
return Settings(settingsStore: context.read<SettingsStore>());
},
);
},
),
IconButton(
icon: const Icon(Icons.stacked_bar_chart),
onPressed: () {

View file

@ -1,18 +1,99 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:frosty/screens/settings.dart';
import 'package:frosty/stores/settings_store.dart';
import 'package:frosty/stores/video_store.dart';
import 'package:webview_flutter/webview_flutter.dart';
class Video extends StatelessWidget {
final String channelName;
final VideoStore videoStore;
final SettingsStore settingsStore;
const Video({Key? key, required this.channelName}) : super(key: key);
const Video({
Key? key,
required this.channelName,
required this.videoStore,
required this.settingsStore,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return WebView(
initialUrl: 'https://player.twitch.tv/?channel=$channelName&muted=false&parent=frosty',
javascriptMode: JavascriptMode.unrestricted,
allowsInlineMediaPlayback: true,
initialMediaPlaybackPolicy: AutoMediaPlaybackPolicy.always_allow,
return Stack(
children: [
WebView(
initialUrl: 'https://player.twitch.tv/?channel=$channelName&muted=false&parent=frosty',
javascriptMode: JavascriptMode.unrestricted,
allowsInlineMediaPlayback: true,
initialMediaPlaybackPolicy: AutoMediaPlaybackPolicy.always_allow,
onWebViewCreated: (controller) {
videoStore.controller = controller;
},
onPageFinished: (string) {
videoStore.removeOverlay();
},
),
GestureDetector(
behavior: HitTestBehavior.opaque,
child: SizedBox.expand(
child: Observer(
builder: (_) {
return AnimatedOpacity(
opacity: videoStore.menuVisible ? 1.0 : 0.0,
duration: const Duration(milliseconds: 100),
child: ColoredBox(
color: Colors.black.withOpacity(0.5),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () => Navigator.of(context).pop(),
),
const Spacer(),
IconButton(
icon: const Icon(Icons.settings),
onPressed: () {
showModalBottomSheet(
context: context,
builder: (context) {
return Settings(settingsStore: settingsStore);
},
);
},
),
],
),
IconButton(
icon: videoStore.paused ? const Icon(Icons.play_arrow) : const Icon(Icons.pause),
onPressed: videoStore.handlePausePlay,
),
Row(
children: [
IconButton(
icon: const Icon(Icons.refresh),
onPressed: () {},
),
const Spacer(),
IconButton(
icon: const Icon(Icons.fullscreen),
onPressed: videoStore.requestFullscreen,
)
],
)
],
),
),
);
},
),
),
onTap: videoStore.handleVideoTap,
),
],
);
}
}