Fix chat not scrolling to end rotating/fullscreen

This commit is contained in:
Tommy Chow 2022-01-24 16:03:17 -05:00
parent e98284be28
commit b17b026ab8
3 changed files with 40 additions and 13 deletions

View file

@ -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: [

View file

@ -76,7 +76,7 @@ abstract class _ChatStoreBase with Store {
@readonly
var _userState = const USERSTATE();
late final ReactionDisposer disposeEmoteMenuReaction;
final reactions = <ReactionDisposer>[];
_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();

View file

@ -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<VideoChat> {
final _videoKey = GlobalKey();
final _chatKey = GlobalKey();
@override
Widget build(BuildContext context) {
@ -88,7 +90,10 @@ class _VideoChatState extends State<VideoChat> {
),
);
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<VideoChat> {
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<VideoChat> {
bottom: false,
child: settingsStore.showVideo
? settingsStore.fullScreen
? video
? Stack(
children: [
Visibility(
visible: false,
maintainState: true,
child: chat,
),
video,
],
)
: Row(
children: [
Flexible(