Fix theme change restarting video/chat, renames
This commit is contained in:
parent
17e9acb84a
commit
26d35a31fe
5 changed files with 74 additions and 111 deletions
|
|
@ -20,13 +20,7 @@ class EmoteMenu extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _EmoteMenuState extends State<EmoteMenu> {
|
||||
late final PageController pageContoller;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
pageContoller = PageController(initialPage: widget.assetsStore.emoteMenuIndex);
|
||||
super.initState();
|
||||
}
|
||||
late final PageController _pageContoller = PageController(initialPage: widget.assetsStore.emoteMenuIndex);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
@ -48,7 +42,7 @@ class _EmoteMenuState extends State<EmoteMenu> {
|
|||
(index, section) => Observer(
|
||||
builder: (context) => TextButton(
|
||||
onPressed: () {
|
||||
pageContoller.animateToPage(
|
||||
_pageContoller.animateToPage(
|
||||
index,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
curve: Curves.ease,
|
||||
|
|
@ -66,7 +60,7 @@ class _EmoteMenuState extends State<EmoteMenu> {
|
|||
Expanded(
|
||||
child: PageView(
|
||||
onPageChanged: (index) => widget.assetsStore.emoteMenuIndex = index,
|
||||
controller: pageContoller,
|
||||
controller: _pageContoller,
|
||||
children: [
|
||||
RecentEmotesPanel(
|
||||
assetsStore: widget.assetsStore,
|
||||
|
|
@ -109,7 +103,7 @@ class _EmoteMenuState extends State<EmoteMenu> {
|
|||
|
||||
@override
|
||||
void dispose() {
|
||||
pageContoller.dispose();
|
||||
_pageContoller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,22 +2,33 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter/scheduler.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:frosty/api/bttv_api.dart';
|
||||
import 'package:frosty/api/ffz_api.dart';
|
||||
import 'package:frosty/api/seventv_api.dart';
|
||||
import 'package:frosty/api/twitch_api.dart';
|
||||
import 'package:frosty/constants/constants.dart';
|
||||
import 'package:frosty/core/auth/auth_store.dart';
|
||||
import 'package:frosty/screens/channel/chat/chat.dart';
|
||||
import 'package:frosty/screens/channel/stores/chat_assets_store.dart';
|
||||
import 'package:frosty/screens/channel/stores/chat_details_store.dart';
|
||||
import 'package:frosty/screens/channel/stores/chat_store.dart';
|
||||
import 'package:frosty/screens/channel/stores/video_store.dart';
|
||||
import 'package:frosty/screens/channel/video/video.dart';
|
||||
import 'package:frosty/screens/channel/video/video_overlay.dart';
|
||||
import 'package:frosty/screens/settings/settings.dart';
|
||||
import 'package:frosty/screens/settings/stores/settings_store.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class VideoChat extends StatefulWidget {
|
||||
final ChatStore chatStore;
|
||||
final String userId;
|
||||
final String userName;
|
||||
final String userLogin;
|
||||
|
||||
const VideoChat({
|
||||
Key? key,
|
||||
required this.chatStore,
|
||||
required this.userId,
|
||||
required this.userName,
|
||||
required this.userLogin,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
|
@ -28,54 +39,70 @@ class _VideoChatState extends State<VideoChat> {
|
|||
final _videoKey = GlobalKey();
|
||||
final _chatKey = GlobalKey();
|
||||
|
||||
late final ChatStore _chatStore = ChatStore(
|
||||
channelName: widget.userLogin,
|
||||
channelId: widget.userId,
|
||||
displayName: widget.userName,
|
||||
auth: context.read<AuthStore>(),
|
||||
settings: context.read<SettingsStore>(),
|
||||
chatDetailsStore: ChatDetailsStore(
|
||||
twitchApi: context.read<TwitchApi>(),
|
||||
),
|
||||
assetsStore: ChatAssetsStore(
|
||||
twitchApi: context.read<TwitchApi>(),
|
||||
ffzApi: context.read<FFZApi>(),
|
||||
bttvApi: context.read<BTTVApi>(),
|
||||
sevenTVApi: context.read<SevenTVApi>(),
|
||||
),
|
||||
);
|
||||
|
||||
late final VideoStore _videoStore = VideoStore(
|
||||
twitchApi: context.read<TwitchApi>(),
|
||||
userLogin: widget.userLogin,
|
||||
authStore: context.read<AuthStore>(),
|
||||
settingsStore: context.read<SettingsStore>(),
|
||||
);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final chatStore = widget.chatStore;
|
||||
final settingsStore = chatStore.settings;
|
||||
|
||||
final videoStore = VideoStore(
|
||||
twitchApi: context.read<TwitchApi>(),
|
||||
userLogin: chatStore.channelName,
|
||||
authStore: chatStore.auth,
|
||||
settingsStore: chatStore.settings,
|
||||
);
|
||||
final settingsStore = _chatStore.settings;
|
||||
|
||||
final player = Video(
|
||||
key: _videoKey,
|
||||
videoStore: videoStore,
|
||||
videoStore: _videoStore,
|
||||
);
|
||||
|
||||
final video = GestureDetector(
|
||||
onLongPress: videoStore.handleToggleOverlay,
|
||||
onLongPress: _videoStore.handleToggleOverlay,
|
||||
onTap: () {
|
||||
if (chatStore.assetsStore.showEmoteMenu) {
|
||||
chatStore.assetsStore.showEmoteMenu = false;
|
||||
if (_chatStore.assetsStore.showEmoteMenu) {
|
||||
_chatStore.assetsStore.showEmoteMenu = false;
|
||||
} else {
|
||||
if (chatStore.textFieldFocusNode.hasFocus) {
|
||||
chatStore.textFieldFocusNode.unfocus();
|
||||
if (_chatStore.textFieldFocusNode.hasFocus) {
|
||||
_chatStore.textFieldFocusNode.unfocus();
|
||||
} else {
|
||||
videoStore.handleVideoTap();
|
||||
_videoStore.handleVideoTap();
|
||||
}
|
||||
}
|
||||
},
|
||||
child: Observer(
|
||||
builder: (context) {
|
||||
if (videoStore.settingsStore.showOverlay) {
|
||||
if (_videoStore.settingsStore.showOverlay) {
|
||||
return Stack(
|
||||
children: [
|
||||
player,
|
||||
Observer(
|
||||
builder: (_) {
|
||||
if (videoStore.paused) return VideoOverlay(videoStore: videoStore);
|
||||
if (_videoStore.paused) return VideoOverlay(videoStore: _videoStore);
|
||||
return Observer(
|
||||
builder: (_) => AnimatedOpacity(
|
||||
opacity: videoStore.overlayVisible ? 1.0 : 0.0,
|
||||
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(videoStore: videoStore),
|
||||
ignoring: !_videoStore.overlayVisible,
|
||||
child: VideoOverlay(videoStore: _videoStore),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -92,12 +119,12 @@ class _VideoChatState extends State<VideoChat> {
|
|||
|
||||
final chat = Chat(
|
||||
key: _chatKey,
|
||||
chatStore: chatStore,
|
||||
chatStore: _chatStore,
|
||||
);
|
||||
|
||||
final appBar = AppBar(
|
||||
title: Text(
|
||||
regexEnglish.hasMatch(chatStore.displayName) ? chatStore.displayName : chatStore.displayName + ' (${chatStore.channelName})',
|
||||
regexEnglish.hasMatch(_chatStore.displayName) ? _chatStore.displayName : _chatStore.displayName + ' (${_chatStore.channelName})',
|
||||
style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||
),
|
||||
actions: [
|
||||
|
|
@ -122,7 +149,7 @@ class _VideoChatState extends State<VideoChat> {
|
|||
if (orientation == Orientation.landscape) {
|
||||
// Add a post-frame callback to scroll to bottom when rotating.
|
||||
SchedulerBinding.instance?.addPostFrameCallback((_) {
|
||||
if (chatStore.scrollController.hasClients) chatStore.scrollController.jumpTo(chatStore.scrollController.position.maxScrollExtent);
|
||||
if (_chatStore.scrollController.hasClients) _chatStore.scrollController.jumpTo(_chatStore.scrollController.position.maxScrollExtent);
|
||||
});
|
||||
|
||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
|
||||
|
|
@ -199,7 +226,7 @@ class _VideoChatState extends State<VideoChat> {
|
|||
|
||||
@override
|
||||
void dispose() {
|
||||
widget.chatStore.dispose();
|
||||
_chatStore.dispose();
|
||||
|
||||
SystemChrome.setEnabledSystemUIMode(
|
||||
SystemUiMode.manual,
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ class Search extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _SearchState extends State<Search> {
|
||||
final textEditingController = TextEditingController();
|
||||
final _textEditingController = TextEditingController();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
@ -28,7 +28,7 @@ class _SearchState extends State<Search> {
|
|||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 5.0, horizontal: 10.0),
|
||||
child: TextField(
|
||||
controller: textEditingController,
|
||||
controller: _textEditingController,
|
||||
autocorrect: false,
|
||||
decoration: InputDecoration(
|
||||
isDense: true,
|
||||
|
|
@ -42,7 +42,7 @@ class _SearchState extends State<Search> {
|
|||
onPressed: () {
|
||||
FocusScope.of(context).unfocus();
|
||||
setState(() {
|
||||
textEditingController.clear();
|
||||
_textEditingController.clear();
|
||||
});
|
||||
},
|
||||
icon: const Icon(Icons.clear),
|
||||
|
|
@ -54,7 +54,7 @@ class _SearchState extends State<Search> {
|
|||
Expanded(
|
||||
child: Observer(
|
||||
builder: (context) {
|
||||
if (textEditingController.text.isEmpty || searchStore.channelFuture == null || searchStore.categoryFuture == null) {
|
||||
if (_textEditingController.text.isEmpty || searchStore.channelFuture == null || searchStore.categoryFuture == null) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
|
|
@ -82,7 +82,7 @@ class _SearchState extends State<Search> {
|
|||
),
|
||||
onTap: () {
|
||||
setState(() {
|
||||
textEditingController.text = searchTerm;
|
||||
_textEditingController.text = searchTerm;
|
||||
searchStore.handleQuery(searchTerm);
|
||||
});
|
||||
},
|
||||
|
|
@ -104,7 +104,7 @@ class _SearchState extends State<Search> {
|
|||
),
|
||||
SearchResultsChannels(
|
||||
searchStore: searchStore,
|
||||
query: textEditingController.text,
|
||||
query: _textEditingController.text,
|
||||
),
|
||||
const SliverToBoxAdapter(
|
||||
child: SectionHeader(
|
||||
|
|
@ -124,7 +124,7 @@ class _SearchState extends State<Search> {
|
|||
|
||||
@override
|
||||
void dispose() {
|
||||
textEditingController.dispose();
|
||||
_textEditingController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +1,12 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:frosty/api/bttv_api.dart';
|
||||
import 'package:frosty/api/ffz_api.dart';
|
||||
import 'package:frosty/api/seventv_api.dart';
|
||||
import 'package:frosty/api/twitch_api.dart';
|
||||
import 'package:frosty/constants/constants.dart';
|
||||
import 'package:frosty/models/channel.dart';
|
||||
import 'package:frosty/screens/channel/stores/chat_assets_store.dart';
|
||||
import 'package:frosty/screens/channel/stores/chat_details_store.dart';
|
||||
import 'package:frosty/screens/channel/stores/chat_store.dart';
|
||||
import 'package:frosty/screens/channel/video_chat.dart';
|
||||
import 'package:frosty/screens/home/stores/search_store.dart';
|
||||
import 'package:frosty/screens/settings/stores/settings_store.dart';
|
||||
import 'package:frosty/widgets/loading_indicator.dart';
|
||||
import 'package:frosty/widgets/profile_picture.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class SearchResultsChannels extends StatelessWidget {
|
||||
final SearchStore searchStore;
|
||||
|
|
@ -34,22 +25,9 @@ class SearchResultsChannels extends StatelessWidget {
|
|||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => VideoChat(
|
||||
chatStore: ChatStore(
|
||||
channelName: channelInfo.broadcasterLogin,
|
||||
channelId: channelInfo.broadcasterId,
|
||||
displayName: channelInfo.broadcasterName,
|
||||
chatDetailsStore: ChatDetailsStore(
|
||||
twitchApi: context.read<TwitchApi>(),
|
||||
),
|
||||
assetsStore: ChatAssetsStore(
|
||||
twitchApi: context.read<TwitchApi>(),
|
||||
ffzApi: context.read<FFZApi>(),
|
||||
bttvApi: context.read<BTTVApi>(),
|
||||
sevenTVApi: context.read<SevenTVApi>(),
|
||||
),
|
||||
auth: searchStore.authStore,
|
||||
settings: context.read<SettingsStore>(),
|
||||
),
|
||||
userId: channelInfo.broadcasterId,
|
||||
userName: channelInfo.broadcasterName,
|
||||
userLogin: channelInfo.broadcasterLogin,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
@ -111,22 +89,9 @@ class SearchResultsChannels extends StatelessWidget {
|
|||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => VideoChat(
|
||||
chatStore: ChatStore(
|
||||
channelName: channel.broadcasterLogin,
|
||||
channelId: channel.id,
|
||||
displayName: channel.displayName,
|
||||
chatDetailsStore: ChatDetailsStore(
|
||||
twitchApi: context.read<TwitchApi>(),
|
||||
),
|
||||
assetsStore: ChatAssetsStore(
|
||||
twitchApi: context.read<TwitchApi>(),
|
||||
ffzApi: context.read<FFZApi>(),
|
||||
bttvApi: context.read<BTTVApi>(),
|
||||
sevenTVApi: context.read<SevenTVApi>(),
|
||||
),
|
||||
auth: searchStore.authStore,
|
||||
settings: context.read<SettingsStore>(),
|
||||
),
|
||||
userId: channel.id,
|
||||
userName: channel.displayName,
|
||||
userLogin: channel.broadcasterLogin,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,21 +1,11 @@
|
|||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:frosty/api/bttv_api.dart';
|
||||
import 'package:frosty/api/ffz_api.dart';
|
||||
import 'package:frosty/api/seventv_api.dart';
|
||||
import 'package:frosty/api/twitch_api.dart';
|
||||
import 'package:frosty/constants/constants.dart';
|
||||
import 'package:frosty/core/auth/auth_store.dart';
|
||||
import 'package:frosty/models/stream.dart';
|
||||
import 'package:frosty/screens/channel/stores/chat_assets_store.dart';
|
||||
import 'package:frosty/screens/channel/stores/chat_details_store.dart';
|
||||
import 'package:frosty/screens/channel/stores/chat_store.dart';
|
||||
import 'package:frosty/screens/channel/video_chat.dart';
|
||||
import 'package:frosty/screens/settings/stores/settings_store.dart';
|
||||
import 'package:frosty/widgets/loading_indicator.dart';
|
||||
import 'package:frosty/widgets/profile_picture.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
/// A tappable card widget that displays a stream's thumbnail and details.
|
||||
class StreamCard extends StatelessWidget {
|
||||
|
|
@ -53,22 +43,9 @@ class StreamCard extends StatelessWidget {
|
|||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => VideoChat(
|
||||
chatStore: ChatStore(
|
||||
channelName: streamInfo.userLogin,
|
||||
channelId: streamInfo.userId,
|
||||
displayName: streamInfo.userName,
|
||||
auth: context.read<AuthStore>(),
|
||||
settings: context.read<SettingsStore>(),
|
||||
chatDetailsStore: ChatDetailsStore(
|
||||
twitchApi: context.read<TwitchApi>(),
|
||||
),
|
||||
assetsStore: ChatAssetsStore(
|
||||
twitchApi: context.read<TwitchApi>(),
|
||||
ffzApi: context.read<FFZApi>(),
|
||||
bttvApi: context.read<BTTVApi>(),
|
||||
sevenTVApi: context.read<SevenTVApi>(),
|
||||
),
|
||||
),
|
||||
userId: streamInfo.userId,
|
||||
userName: streamInfo.userName,
|
||||
userLogin: streamInfo.userLogin,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue