Add bg opacity option to overlay chat (#130)
This commit is contained in:
parent
07c260def5
commit
2b6e683cae
6 changed files with 178 additions and 135 deletions
150
lib/main.dart
150
lib/main.dart
|
|
@ -75,86 +75,86 @@ void main() async {
|
|||
// Navigator key for sleep timer. Allows navigation popping without context.
|
||||
final navigatorKey = GlobalKey<NavigatorState>();
|
||||
|
||||
const gray = Color.fromRGBO(22, 22, 22, 1.0);
|
||||
const purple = Color(0xff9146ff);
|
||||
|
||||
final lightTheme = ThemeData(
|
||||
canvasColor: Colors.white,
|
||||
splashFactory: Platform.isIOS ? NoSplash.splashFactory : null,
|
||||
fontFamily: 'Inter',
|
||||
appBarTheme: const AppBarTheme(
|
||||
color: Colors.white,
|
||||
elevation: 0.0,
|
||||
titleTextStyle: TextStyle(
|
||||
fontFamily: 'Inter',
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black,
|
||||
),
|
||||
iconTheme: IconThemeData(color: Colors.black),
|
||||
),
|
||||
colorScheme: ColorScheme.fromSwatch(
|
||||
primarySwatch: Colors.deepPurple,
|
||||
accentColor: purple,
|
||||
),
|
||||
toggleableActiveColor: purple,
|
||||
tabBarTheme: const TabBarTheme(
|
||||
labelColor: Colors.black,
|
||||
unselectedLabelColor: Colors.grey,
|
||||
),
|
||||
);
|
||||
|
||||
final darkTheme = ThemeData(
|
||||
canvasColor: gray,
|
||||
brightness: Brightness.dark,
|
||||
splashFactory: Platform.isIOS ? NoSplash.splashFactory : null,
|
||||
fontFamily: 'Inter',
|
||||
appBarTheme: const AppBarTheme(
|
||||
color: gray,
|
||||
elevation: 0.0,
|
||||
titleTextStyle: TextStyle(
|
||||
fontFamily: 'Inter',
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
bottomNavigationBarTheme: const BottomNavigationBarThemeData(backgroundColor: gray),
|
||||
colorScheme: ColorScheme.fromSwatch(
|
||||
brightness: Brightness.dark,
|
||||
primarySwatch: Colors.deepPurple,
|
||||
accentColor: purple,
|
||||
),
|
||||
dialogBackgroundColor: gray,
|
||||
toggleableActiveColor: purple,
|
||||
);
|
||||
|
||||
final oledTheme = ThemeData(
|
||||
canvasColor: Colors.black,
|
||||
splashFactory: Platform.isIOS ? NoSplash.splashFactory : null,
|
||||
fontFamily: 'Inter',
|
||||
appBarTheme: const AppBarTheme(
|
||||
color: Colors.black,
|
||||
elevation: 0.0,
|
||||
titleTextStyle: TextStyle(
|
||||
fontFamily: 'Inter',
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
colorScheme: ColorScheme.fromSwatch(
|
||||
brightness: Brightness.dark,
|
||||
primarySwatch: Colors.deepPurple,
|
||||
accentColor: purple,
|
||||
),
|
||||
dialogBackgroundColor: Colors.black,
|
||||
toggleableActiveColor: purple,
|
||||
);
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
const MyApp({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
const gray = Color.fromRGBO(22, 22, 22, 1.0);
|
||||
const purple = Color(0xff9146ff);
|
||||
|
||||
final lightTheme = ThemeData(
|
||||
canvasColor: Colors.white,
|
||||
splashFactory: Platform.isIOS ? NoSplash.splashFactory : null,
|
||||
fontFamily: 'Inter',
|
||||
appBarTheme: const AppBarTheme(
|
||||
color: Colors.white,
|
||||
elevation: 0.0,
|
||||
titleTextStyle: TextStyle(
|
||||
fontFamily: 'Inter',
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black,
|
||||
),
|
||||
iconTheme: IconThemeData(color: Colors.black),
|
||||
),
|
||||
colorScheme: ColorScheme.fromSwatch(
|
||||
primarySwatch: Colors.deepPurple,
|
||||
accentColor: purple,
|
||||
),
|
||||
toggleableActiveColor: purple,
|
||||
tabBarTheme: const TabBarTheme(
|
||||
labelColor: Colors.black,
|
||||
unselectedLabelColor: Colors.grey,
|
||||
),
|
||||
);
|
||||
|
||||
final darkTheme = ThemeData(
|
||||
canvasColor: gray,
|
||||
brightness: Brightness.dark,
|
||||
splashFactory: Platform.isIOS ? NoSplash.splashFactory : null,
|
||||
fontFamily: 'Inter',
|
||||
appBarTheme: const AppBarTheme(
|
||||
color: gray,
|
||||
elevation: 0.0,
|
||||
titleTextStyle: TextStyle(
|
||||
fontFamily: 'Inter',
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
bottomNavigationBarTheme: const BottomNavigationBarThemeData(backgroundColor: gray),
|
||||
colorScheme: ColorScheme.fromSwatch(
|
||||
brightness: Brightness.dark,
|
||||
primarySwatch: Colors.deepPurple,
|
||||
accentColor: purple,
|
||||
),
|
||||
dialogBackgroundColor: gray,
|
||||
toggleableActiveColor: purple,
|
||||
);
|
||||
|
||||
final oledTheme = ThemeData(
|
||||
canvasColor: Colors.black,
|
||||
splashFactory: Platform.isIOS ? NoSplash.splashFactory : null,
|
||||
fontFamily: 'Inter',
|
||||
appBarTheme: const AppBarTheme(
|
||||
color: Colors.black,
|
||||
elevation: 0.0,
|
||||
titleTextStyle: TextStyle(
|
||||
fontFamily: 'Inter',
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
colorScheme: ColorScheme.fromSwatch(
|
||||
brightness: Brightness.dark,
|
||||
primarySwatch: Colors.deepPurple,
|
||||
accentColor: purple,
|
||||
),
|
||||
dialogBackgroundColor: Colors.black,
|
||||
toggleableActiveColor: purple,
|
||||
);
|
||||
|
||||
return Observer(
|
||||
builder: (context) {
|
||||
final settingsStore = context.read<SettingsStore>();
|
||||
|
|
|
|||
|
|
@ -108,8 +108,7 @@ class Chat extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
if (chatStore.settings.showBottomBar && (!chatStore.settings.fullScreen || MediaQuery.of(context).orientation == Orientation.portrait))
|
||||
ChatBottomBar(chatStore: chatStore),
|
||||
if (chatStore.settings.showBottomBar) ChatBottomBar(chatStore: chatStore),
|
||||
if (chatStore.assetsStore.showEmoteMenu)
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).size.height / 3,
|
||||
|
|
|
|||
|
|
@ -77,9 +77,9 @@ class _VideoChatState extends State<VideoChat> {
|
|||
videoStore: _videoStore,
|
||||
);
|
||||
|
||||
final overlay = VideoOverlay(videoStore: _videoStore);
|
||||
final videoOverlay = VideoOverlay(videoStore: _videoStore);
|
||||
|
||||
final video = GestureDetector(
|
||||
final overlay = GestureDetector(
|
||||
onLongPress: _videoStore.handleToggleOverlay,
|
||||
onTap: () {
|
||||
if (_chatStore.assetsStore.showEmoteMenu) {
|
||||
|
|
@ -93,33 +93,37 @@ class _VideoChatState extends State<VideoChat> {
|
|||
}
|
||||
},
|
||||
child: Observer(
|
||||
builder: (context) {
|
||||
if (_videoStore.settingsStore.showOverlay) {
|
||||
return Stack(
|
||||
children: [
|
||||
player,
|
||||
if (_videoStore.paused || _videoStore.streamInfo == null)
|
||||
overlay
|
||||
else
|
||||
AnimatedOpacity(
|
||||
opacity: _videoStore.overlayVisible ? 1.0 : 0.0,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: ColoredBox(
|
||||
color: const Color.fromRGBO(0, 0, 0, 0.5),
|
||||
child: IgnorePointer(
|
||||
ignoring: !_videoStore.overlayVisible,
|
||||
child: overlay,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
return player;
|
||||
builder: (_) {
|
||||
if (_videoStore.paused || _videoStore.streamInfo == null) return videoOverlay;
|
||||
|
||||
return AnimatedOpacity(
|
||||
opacity: _videoStore.overlayVisible ? 1.0 : 0.0,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
child: ColoredBox(
|
||||
color: const Color.fromRGBO(0, 0, 0, 0.5),
|
||||
child: IgnorePointer(
|
||||
ignoring: !_videoStore.overlayVisible,
|
||||
child: videoOverlay,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
final video = Observer(
|
||||
builder: (context) {
|
||||
if (!_videoStore.settingsStore.showOverlay) return player;
|
||||
|
||||
return Stack(
|
||||
children: [
|
||||
player,
|
||||
overlay,
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
final chat = Chat(
|
||||
key: _chatKey,
|
||||
chatStore: _chatStore,
|
||||
|
|
@ -165,10 +169,24 @@ class _VideoChatState extends State<VideoChat> {
|
|||
? MediaQuery.of(context).size.width / 2
|
||||
: MediaQuery.of(context).size.width * _chatStore.settings.landscapeChatWidth,
|
||||
curve: Curves.ease,
|
||||
color: _chatStore.settings.fullScreen ? null : Theme.of(context).scaffoldBackgroundColor,
|
||||
color: _chatStore.settings.fullScreen
|
||||
? Colors.black.withOpacity(_chatStore.settings.fullScreenChatOverlayOpacity)
|
||||
: Theme.of(context).scaffoldBackgroundColor,
|
||||
child: chat,
|
||||
);
|
||||
|
||||
final overlayChat = Visibility(
|
||||
visible: settingsStore.fullScreenChatOverlay,
|
||||
maintainState: true,
|
||||
child: Theme(
|
||||
data: darkTheme,
|
||||
child: DefaultTextStyle(
|
||||
style: DefaultTextStyle.of(context).style.copyWith(color: Colors.white),
|
||||
child: landscapeChat,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return ColoredBox(
|
||||
color: settingsStore.showVideo ? Colors.black : Theme.of(context).scaffoldBackgroundColor,
|
||||
child: SafeArea(
|
||||
|
|
@ -176,38 +194,22 @@ class _VideoChatState extends State<VideoChat> {
|
|||
child: settingsStore.showVideo
|
||||
? settingsStore.fullScreen
|
||||
? Stack(
|
||||
alignment: settingsStore.landscapeChatLeftSide ? Alignment.topLeft : Alignment.topRight,
|
||||
children: [
|
||||
video,
|
||||
IgnorePointer(
|
||||
ignoring: _videoStore.overlayVisible,
|
||||
child: Visibility(
|
||||
visible: settingsStore.fullScreenChatOverlay,
|
||||
maintainState: true,
|
||||
child: DefaultTextStyle(
|
||||
style: DefaultTextStyle.of(context).style.copyWith(color: Colors.white),
|
||||
child: landscapeChat,
|
||||
),
|
||||
),
|
||||
),
|
||||
player,
|
||||
Row(
|
||||
children: settingsStore.landscapeChatLeftSide
|
||||
? [overlayChat, Expanded(child: overlay)]
|
||||
: [Expanded(child: overlay), overlayChat],
|
||||
)
|
||||
],
|
||||
)
|
||||
: Row(
|
||||
children: settingsStore.landscapeChatLeftSide
|
||||
? [
|
||||
landscapeChat,
|
||||
Expanded(child: video),
|
||||
]
|
||||
: [
|
||||
Expanded(child: video),
|
||||
landscapeChat,
|
||||
],
|
||||
? [landscapeChat, Expanded(child: video)]
|
||||
: [Expanded(child: video), landscapeChat],
|
||||
)
|
||||
: Column(
|
||||
children: [
|
||||
appBar,
|
||||
Expanded(child: chat),
|
||||
],
|
||||
children: [appBar, Expanded(child: chat)],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
@ -224,13 +226,9 @@ class _VideoChatState extends State<VideoChat> {
|
|||
children: [
|
||||
Observer(
|
||||
builder: (_) {
|
||||
if (settingsStore.showVideo) {
|
||||
return AspectRatio(
|
||||
aspectRatio: 16 / 9,
|
||||
child: video,
|
||||
);
|
||||
}
|
||||
return appBar;
|
||||
if (!settingsStore.showVideo) return appBar;
|
||||
|
||||
return AspectRatio(aspectRatio: 16 / 9, child: video);
|
||||
},
|
||||
),
|
||||
Expanded(child: chat),
|
||||
|
|
|
|||
|
|
@ -86,6 +86,23 @@ class _ChatSettingsState extends State<ChatSettings> {
|
|||
onChanged: (newValue) => settingsStore.landscapeChatWidth = newValue,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 15.0),
|
||||
ListTile(
|
||||
title: Row(
|
||||
children: [
|
||||
const Text('Landscape Chat Overlay Opacity'),
|
||||
const Spacer(),
|
||||
Text('${(settingsStore.fullScreenChatOverlayOpacity * 100).toStringAsFixed(0)}%'),
|
||||
],
|
||||
),
|
||||
subtitle: Slider.adaptive(
|
||||
value: settingsStore.fullScreenChatOverlayOpacity,
|
||||
min: 0.0,
|
||||
max: 1.0,
|
||||
divisions: 10,
|
||||
onChanged: (newValue) => settingsStore.fullScreenChatOverlayOpacity = newValue,
|
||||
),
|
||||
),
|
||||
const SectionHeader(
|
||||
'Emotes',
|
||||
fontSize: 12.0,
|
||||
|
|
|
|||
|
|
@ -93,6 +93,8 @@ abstract class _SettingsStoreBase with Store {
|
|||
|
||||
static const defaultChatDelay = 0.0;
|
||||
|
||||
static const defaultFullScreenChatOverlayOpacity = 0.5;
|
||||
|
||||
@JsonKey(defaultValue: defaultShowBottomBar)
|
||||
@observable
|
||||
var showBottomBar = defaultShowBottomBar;
|
||||
|
|
@ -149,6 +151,10 @@ abstract class _SettingsStoreBase with Store {
|
|||
@observable
|
||||
var landscapeChatLeftSide = defaultLandscapeChatLeftSide;
|
||||
|
||||
@JsonKey(defaultValue: defaultFullScreenChatOverlayOpacity)
|
||||
@observable
|
||||
var fullScreenChatOverlayOpacity = defaultFullScreenChatOverlayOpacity;
|
||||
|
||||
// * Other settings
|
||||
static const defaultSendCrashLogs = true;
|
||||
|
||||
|
|
@ -209,6 +215,7 @@ abstract class _SettingsStoreBase with Store {
|
|||
landscapeChatWidth = defaultLandscapeChatWidth;
|
||||
landscapeChatLeftSide = false;
|
||||
chatDelay = defaultChatDelay;
|
||||
fullScreenChatOverlayOpacity = defaultFullScreenChatOverlayOpacity;
|
||||
|
||||
// * Other settings
|
||||
sendCrashLogs = defaultSendCrashLogs;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ SettingsStore _$SettingsStoreFromJson(Map<String, dynamic> json) =>
|
|||
..landscapeChatWidth =
|
||||
(json['landscapeChatWidth'] as num?)?.toDouble() ?? 0.3
|
||||
..landscapeChatLeftSide = json['landscapeChatLeftSide'] as bool? ?? false
|
||||
..fullScreenChatOverlayOpacity =
|
||||
(json['fullScreenChatOverlayOpacity'] as num?)?.toDouble() ?? 0.5
|
||||
..sendCrashLogs = json['sendCrashLogs'] as bool? ?? true
|
||||
..fullScreen = json['fullScreen'] as bool? ?? false
|
||||
..expandInfo = json['expandInfo'] as bool? ?? true
|
||||
|
|
@ -67,6 +69,7 @@ Map<String, dynamic> _$SettingsStoreToJson(SettingsStore instance) =>
|
|||
'emoteAutocomplete': instance.emoteAutocomplete,
|
||||
'landscapeChatWidth': instance.landscapeChatWidth,
|
||||
'landscapeChatLeftSide': instance.landscapeChatLeftSide,
|
||||
'fullScreenChatOverlayOpacity': instance.fullScreenChatOverlayOpacity,
|
||||
'sendCrashLogs': instance.sendCrashLogs,
|
||||
'fullScreen': instance.fullScreen,
|
||||
'expandInfo': instance.expandInfo,
|
||||
|
|
@ -448,6 +451,24 @@ mixin _$SettingsStore on _SettingsStoreBase, Store {
|
|||
});
|
||||
}
|
||||
|
||||
late final _$fullScreenChatOverlayOpacityAtom = Atom(
|
||||
name: '_SettingsStoreBase.fullScreenChatOverlayOpacity',
|
||||
context: context);
|
||||
|
||||
@override
|
||||
double get fullScreenChatOverlayOpacity {
|
||||
_$fullScreenChatOverlayOpacityAtom.reportRead();
|
||||
return super.fullScreenChatOverlayOpacity;
|
||||
}
|
||||
|
||||
@override
|
||||
set fullScreenChatOverlayOpacity(double value) {
|
||||
_$fullScreenChatOverlayOpacityAtom
|
||||
.reportWrite(value, super.fullScreenChatOverlayOpacity, () {
|
||||
super.fullScreenChatOverlayOpacity = value;
|
||||
});
|
||||
}
|
||||
|
||||
late final _$sendCrashLogsAtom =
|
||||
Atom(name: '_SettingsStoreBase.sendCrashLogs', context: context);
|
||||
|
||||
|
|
@ -568,6 +589,7 @@ emoteScale: ${emoteScale},
|
|||
emoteAutocomplete: ${emoteAutocomplete},
|
||||
landscapeChatWidth: ${landscapeChatWidth},
|
||||
landscapeChatLeftSide: ${landscapeChatLeftSide},
|
||||
fullScreenChatOverlayOpacity: ${fullScreenChatOverlayOpacity},
|
||||
sendCrashLogs: ${sendCrashLogs},
|
||||
fullScreen: ${fullScreen},
|
||||
expandInfo: ${expandInfo},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue