From b17b026ab815930b8eb5eb17ef1db678fe0bb81e Mon Sep 17 00:00:00 2001 From: Tommy Chow Date: Mon, 24 Jan 2022 16:03:17 -0500 Subject: [PATCH] Fix chat not scrolling to end rotating/fullscreen --- lib/screens/channel/chat/chat.dart | 5 ----- lib/screens/channel/stores/chat_store.dart | 24 ++++++++++++++++------ lib/screens/channel/video_chat.dart | 24 ++++++++++++++++++++-- 3 files changed, 40 insertions(+), 13 deletions(-) diff --git a/lib/screens/channel/chat/chat.dart b/lib/screens/channel/chat/chat.dart index b5848f27..be5aabcd 100644 --- a/lib/screens/channel/chat/chat.dart +++ b/lib/screens/channel/chat/chat.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:flutter/scheduler.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:frosty/screens/channel/chat/emote_menu/emote_menu.dart'; import 'package:frosty/screens/channel/chat/widgets/chat_bottom_bar.dart'; @@ -14,10 +13,6 @@ class Chat extends StatelessWidget { @override Widget build(BuildContext context) { - // Add a post-frame callback to scroll to bottom when rotating or entering full-screen. - SchedulerBinding.instance?.addPostFrameCallback((_) { - if (chatStore.scrollController.hasClients) chatStore.resumeScroll(); - }); return Observer( builder: (context) => Column( children: [ diff --git a/lib/screens/channel/stores/chat_store.dart b/lib/screens/channel/stores/chat_store.dart index efab450b..7d65cd28 100644 --- a/lib/screens/channel/stores/chat_store.dart +++ b/lib/screens/channel/stores/chat_store.dart @@ -76,7 +76,7 @@ abstract class _ChatStoreBase with Store { @readonly var _userState = const USERSTATE(); - late final ReactionDisposer disposeEmoteMenuReaction; + final reactions = []; _ChatStoreBase({ required this.auth, @@ -90,11 +90,20 @@ abstract class _ChatStoreBase with Store { // Create a reaction where anytime the emote menu is shown or hidden, // scroll to the bottom of the list. This will prevent the emote menu // from covering the latest messages when summoned. - disposeEmoteMenuReaction = reaction((_) => assetsStore.showEmoteMenu, (_) { - SchedulerBinding.instance?.addPostFrameCallback((_) { + reactions.add(reaction( + (_) => assetsStore.showEmoteMenu, + (_) => SchedulerBinding.instance?.addPostFrameCallback((_) { if (scrollController.hasClients) scrollController.jumpTo(scrollController.position.maxScrollExtent); - }); - }); + }), + )); + + // Create a reaction for scrolling to bottom when exiting fullscreen. + reactions.add(reaction( + (_) => settings.fullScreen, + (_) => SchedulerBinding.instance?.addPostFrameCallback((_) { + if (scrollController.hasClients) scrollController.jumpTo(scrollController.position.maxScrollExtent); + }), + )); assetsStore.init(); @@ -337,7 +346,10 @@ abstract class _ChatStoreBase with Store { _channel?.sink.close(1001); _channel = null; - disposeEmoteMenuReaction(); + for (final reactionDisposer in reactions) { + reactionDisposer(); + } + textController.dispose(); scrollController.dispose(); assetsStore.dispose(); diff --git a/lib/screens/channel/video_chat.dart b/lib/screens/channel/video_chat.dart index afe5dfbc..a986f4b5 100644 --- a/lib/screens/channel/video_chat.dart +++ b/lib/screens/channel/video_chat.dart @@ -1,4 +1,5 @@ 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/twitch_api.dart'; @@ -25,6 +26,7 @@ class VideoChat extends StatefulWidget { class _VideoChatState extends State { final _videoKey = GlobalKey(); + final _chatKey = GlobalKey(); @override Widget build(BuildContext context) { @@ -88,7 +90,10 @@ class _VideoChatState extends State { ), ); - final chat = Chat(chatStore: chatStore); + final chat = Chat( + key: _chatKey, + chatStore: chatStore, + ); final appBar = AppBar( title: Text( @@ -115,7 +120,13 @@ class _VideoChatState extends State { body: OrientationBuilder( builder: (context, orientation) { 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); + }); + SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky); + return Observer( builder: (context) => ColoredBox( color: settingsStore.showVideo ? Colors.black : Theme.of(context).scaffoldBackgroundColor, @@ -123,7 +134,16 @@ class _VideoChatState extends State { bottom: false, child: settingsStore.showVideo ? settingsStore.fullScreen - ? video + ? Stack( + children: [ + Visibility( + visible: false, + maintainState: true, + child: chat, + ), + video, + ], + ) : Row( children: [ Flexible(