Fix rotate logic & add detail expansion on overlay
This commit is contained in:
parent
89b54ff08e
commit
0798fbb4ea
4 changed files with 179 additions and 100 deletions
|
|
@ -1,3 +1,5 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:frosty/core/settings/settings.dart';
|
||||
|
|
@ -13,6 +15,8 @@ class VideoOverlay extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final portrait = MediaQuery.of(context).orientation == Orientation.portrait;
|
||||
|
||||
return GestureDetector(
|
||||
onTap: videoStore.handleVideoTap,
|
||||
child: SizedBox.expand(
|
||||
|
|
@ -31,13 +35,14 @@ class VideoOverlay extends StatelessWidget {
|
|||
children: [
|
||||
Row(
|
||||
children: [
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
Icons.adaptive.arrow_back,
|
||||
color: const Color(0xFFFFFFFF),
|
||||
if (portrait)
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
Icons.adaptive.arrow_back,
|
||||
color: const Color(0xFFFFFFFF),
|
||||
),
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
),
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
),
|
||||
const Spacer(),
|
||||
IconButton(
|
||||
icon: const Icon(
|
||||
|
|
@ -58,45 +63,64 @@ class VideoOverlay extends StatelessWidget {
|
|||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: videoStore.streamInfo != null
|
||||
? Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
videoStore.streamInfo!.userName,
|
||||
style: const TextStyle(
|
||||
color: Color(0xFFFFFFFF),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 5.0),
|
||||
Text(
|
||||
videoStore.streamInfo!.title,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
const SizedBox(height: 5.0),
|
||||
Text(
|
||||
'${videoStore.streamInfo?.gameName} for ${NumberFormat().format(videoStore.streamInfo?.viewerCount)} viewers',
|
||||
style: const TextStyle(
|
||||
color: Color(0xFFFFFFFF),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: null,
|
||||
child: GestureDetector(
|
||||
onTap: videoStore.handleExpand,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: videoStore.streamInfo != null
|
||||
? AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
child: videoStore.expandInfo
|
||||
? Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
videoStore.streamInfo!.userName,
|
||||
style: const TextStyle(
|
||||
color: Color(0xFFFFFFFF),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 5.0),
|
||||
Text(
|
||||
videoStore.streamInfo!.title,
|
||||
maxLines: portrait ? 2 : 4,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
const SizedBox(height: 5.0),
|
||||
Text(
|
||||
'${videoStore.streamInfo?.gameName} for ${NumberFormat().format(videoStore.streamInfo?.viewerCount)} viewers',
|
||||
style: const TextStyle(
|
||||
color: Color(0xFFFFFFFF),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Align(
|
||||
alignment: Alignment.bottomLeft,
|
||||
child: Text(
|
||||
videoStore.streamInfo!.userName,
|
||||
style: const TextStyle(
|
||||
color: Color(0xFFFFFFFF),
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(
|
||||
Icons.picture_in_picture_alt_rounded,
|
||||
color: Color(0xFFFFFFFF),
|
||||
if (Platform.isIOS)
|
||||
IconButton(
|
||||
icon: const Icon(
|
||||
Icons.picture_in_picture_alt_rounded,
|
||||
color: Color(0xFFFFFFFF),
|
||||
),
|
||||
onPressed: videoStore.requestPictureInPicture,
|
||||
),
|
||||
onPressed: videoStore.requestPictureInPicture,
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(
|
||||
Icons.fullscreen,
|
||||
|
|
|
|||
|
|
@ -21,6 +21,9 @@ abstract class _VideoStoreBase with Store {
|
|||
@readonly
|
||||
var _paused = false;
|
||||
|
||||
@readonly
|
||||
var _expandInfo = false;
|
||||
|
||||
@readonly
|
||||
StreamTwitch? _streamInfo;
|
||||
|
||||
|
|
@ -68,6 +71,13 @@ abstract class _VideoStoreBase with Store {
|
|||
}
|
||||
}
|
||||
|
||||
@action
|
||||
void handleExpand() {
|
||||
overlayTimer.cancel();
|
||||
_expandInfo = !_expandInfo;
|
||||
overlayTimer = Timer(const Duration(seconds: 5), () => _menuVisible = false);
|
||||
}
|
||||
|
||||
void initVideo() {
|
||||
controller?.runJavascript('document.getElementsByTagName("button")[0].click();');
|
||||
controller?.runJavascript('document.getElementsByTagName("video")[0].muted = false;');
|
||||
|
|
|
|||
|
|
@ -43,6 +43,23 @@ mixin _$VideoStore on _VideoStoreBase, Store {
|
|||
});
|
||||
}
|
||||
|
||||
final _$_expandInfoAtom = Atom(name: '_VideoStoreBase._expandInfo');
|
||||
|
||||
bool get expandInfo {
|
||||
_$_expandInfoAtom.reportRead();
|
||||
return super._expandInfo;
|
||||
}
|
||||
|
||||
@override
|
||||
bool get _expandInfo => expandInfo;
|
||||
|
||||
@override
|
||||
set _expandInfo(bool value) {
|
||||
_$_expandInfoAtom.reportWrite(value, super._expandInfo, () {
|
||||
super._expandInfo = value;
|
||||
});
|
||||
}
|
||||
|
||||
final _$_streamInfoAtom = Atom(name: '_VideoStoreBase._streamInfo');
|
||||
|
||||
StreamTwitch? get streamInfo {
|
||||
|
|
@ -93,6 +110,17 @@ mixin _$VideoStore on _VideoStoreBase, Store {
|
|||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void handleExpand() {
|
||||
final _$actionInfo = _$_VideoStoreBaseActionController.startAction(
|
||||
name: '_VideoStoreBase.handleExpand');
|
||||
try {
|
||||
return super.handleExpand();
|
||||
} finally {
|
||||
_$_VideoStoreBaseActionController.endAction(_$actionInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return '''
|
||||
|
|
|
|||
|
|
@ -42,72 +42,89 @@ class VideoChat extends StatelessWidget {
|
|||
),
|
||||
);
|
||||
|
||||
return Scaffold(
|
||||
body: OrientationBuilder(builder: (context, orientation) {
|
||||
if (orientation == Orientation.landscape) {
|
||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive);
|
||||
return Observer(
|
||||
final appBar = AppBar(
|
||||
title: Text(
|
||||
userName,
|
||||
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||
),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.settings),
|
||||
onPressed: () => showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
if (context.read<SettingsStore>().fullScreen) {
|
||||
return Stack(
|
||||
children: [
|
||||
Visibility(
|
||||
visible: false,
|
||||
maintainState: true,
|
||||
child: chat,
|
||||
),
|
||||
Center(child: video),
|
||||
],
|
||||
);
|
||||
}
|
||||
return Row(
|
||||
children: [
|
||||
Flexible(
|
||||
flex: 2,
|
||||
child: video,
|
||||
),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: chat,
|
||||
),
|
||||
],
|
||||
);
|
||||
return Settings(settingsStore: context.read<SettingsStore>());
|
||||
},
|
||||
);
|
||||
}
|
||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.bottom, SystemUiOverlay.top]);
|
||||
return Column(
|
||||
children: [
|
||||
Observer(
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
return Scaffold(
|
||||
body: OrientationBuilder(
|
||||
builder: (context, orientation) {
|
||||
if (orientation == Orientation.landscape) {
|
||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersive);
|
||||
return Observer(
|
||||
builder: (context) {
|
||||
if (context.read<SettingsStore>().videoEnabled) {
|
||||
return video;
|
||||
}
|
||||
return AppBar(
|
||||
title: Text(
|
||||
userName,
|
||||
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||
),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.settings),
|
||||
onPressed: () => showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return Settings(settingsStore: context.read<SettingsStore>());
|
||||
},
|
||||
),
|
||||
return WillPopScope(
|
||||
onWillPop: () async => false,
|
||||
child: Observer(
|
||||
builder: (context) => context.read<SettingsStore>().fullScreen
|
||||
? Stack(
|
||||
children: [
|
||||
Visibility(
|
||||
visible: false,
|
||||
maintainState: true,
|
||||
child: chat,
|
||||
),
|
||||
Center(child: video),
|
||||
],
|
||||
)
|
||||
: Row(
|
||||
children: [
|
||||
Flexible(
|
||||
flex: 2,
|
||||
child: video,
|
||||
),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: chat,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return Column(
|
||||
children: [
|
||||
appBar,
|
||||
Expanded(child: chat),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
Expanded(
|
||||
child: chat,
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [SystemUiOverlay.bottom, SystemUiOverlay.top]);
|
||||
return Column(
|
||||
children: [
|
||||
Observer(
|
||||
builder: (context) {
|
||||
if (context.read<SettingsStore>().videoEnabled) {
|
||||
return video;
|
||||
}
|
||||
return appBar;
|
||||
},
|
||||
),
|
||||
Expanded(
|
||||
child: chat,
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue