fix landscape bottom padding in chat bottom bar

This commit is contained in:
Tommy Chow 2026-01-09 01:47:02 -05:00
parent f383c447f5
commit 260348736d
2 changed files with 115 additions and 79 deletions

View file

@ -53,46 +53,58 @@ class Chat extends StatelessWidget {
style: context.defaultTextStyle.copyWith(
fontSize: chatStore.settings.fontSize,
),
child: FrostyScrollbar(
controller: chatStore.scrollController,
padding: EdgeInsets.only(
top: MediaQuery.of(context).padding.top,
bottom:
chatStore.bottomBarHeight +
(chatStore.assetsStore.showEmoteMenu
? 0
: MediaQuery.of(context).padding.bottom),
),
child: Observer(
builder: (context) {
return ListView.builder(
reverse: true,
padding: (listPadding ?? EdgeInsets.zero).add(
EdgeInsets.only(
bottom:
chatStore.bottomBarHeight +
(chatStore.assetsStore.showEmoteMenu
? 0
: MediaQuery.of(
context,
).padding.bottom),
),
),
addAutomaticKeepAlives: false,
controller: chatStore.scrollController,
itemCount: chatStore.renderMessages.length,
itemBuilder: (context, index) => ChatMessage(
ircMessage:
chatStore.renderMessages[chatStore
.renderMessages
.length -
1 -
index],
chatStore: chatStore,
),
);
},
),
child: Builder(
builder: (context) {
// Don't add bottom padding in horizontal landscape
// (immersive mode with home indicator on side).
// landscapeForceVerticalChat uses portrait layout
// with normal system UI, so still needs padding.
final isHorizontalLandscape =
context.isLandscape &&
!chatStore.settings.landscapeForceVerticalChat;
final bottomPadding =
chatStore.assetsStore.showEmoteMenu ||
isHorizontalLandscape
? 0.0
: MediaQuery.of(context).padding.bottom;
return FrostyScrollbar(
controller: chatStore.scrollController,
padding: EdgeInsets.only(
top: MediaQuery.of(context).padding.top,
bottom:
chatStore.bottomBarHeight + bottomPadding,
),
child: Observer(
builder: (context) {
return ListView.builder(
reverse: true,
padding: (listPadding ?? EdgeInsets.zero)
.add(
EdgeInsets.only(
bottom:
chatStore.bottomBarHeight +
bottomPadding,
),
),
addAutomaticKeepAlives: false,
controller: chatStore.scrollController,
itemCount: chatStore.renderMessages.length,
itemBuilder: (context, index) =>
ChatMessage(
ircMessage:
chatStore.renderMessages[chatStore
.renderMessages
.length -
1 -
index],
chatStore: chatStore,
),
);
},
),
);
},
),
),
),
@ -119,41 +131,51 @@ class Chat extends StatelessWidget {
onAddChat: onAddChat,
),
),
AnimatedPadding(
duration: const Duration(milliseconds: 200),
padding: EdgeInsets.only(
left: 4,
top: 4,
right: 4,
bottom:
chatStore.bottomBarHeight +
(chatStore.assetsStore.showEmoteMenu
? 0
: MediaQuery.of(context).padding.bottom),
),
child: Observer(
builder: (_) => AnimatedSwitcher(
Builder(
builder: (context) {
final isHorizontalLandscape =
context.isLandscape &&
!chatStore.settings.landscapeForceVerticalChat;
return AnimatedPadding(
duration: const Duration(milliseconds: 200),
switchInCurve: Curves.easeOut,
switchOutCurve: Curves.easeIn,
child: chatStore.autoScroll
? null
: ElevatedButton.icon(
onPressed: chatStore.resumeScroll,
icon: const Icon(Icons.arrow_downward_rounded),
label: Text(
chatStore.messageBuffer.isNotEmpty
? '${chatStore.messageBuffer.length} new ${chatStore.messageBuffer.length == 1 ? 'message' : 'messages'}'
: 'Resume scroll',
style: const TextStyle(
fontFeatures: [
FontFeature.tabularFigures(),
],
padding: EdgeInsets.only(
left: 4,
top: 4,
right: 4,
bottom:
chatStore.bottomBarHeight +
(chatStore.assetsStore.showEmoteMenu ||
isHorizontalLandscape
? 0
: MediaQuery.of(context).padding.bottom),
),
child: Observer(
builder: (_) => AnimatedSwitcher(
duration: const Duration(milliseconds: 200),
switchInCurve: Curves.easeOut,
switchOutCurve: Curves.easeIn,
child: chatStore.autoScroll
? null
: ElevatedButton.icon(
onPressed: chatStore.resumeScroll,
icon: const Icon(
Icons.arrow_downward_rounded,
),
label: Text(
chatStore.messageBuffer.isNotEmpty
? '${chatStore.messageBuffer.length} new ${chatStore.messageBuffer.length == 1 ? 'message' : 'messages'}'
: 'Resume scroll',
style: const TextStyle(
fontFeatures: [
FontFeature.tabularFigures(),
],
),
),
),
),
),
),
),
),
),
);
},
),
],
),

View file

@ -367,21 +367,35 @@ class ChatBottomBar extends StatelessWidget {
],
);
// Don't add bottom padding when:
// - Emote menu is open: The emote menu provides its own bottom boundary
// - In horizontal landscape mode: System is in immersive mode and home
// indicator is on the side (left/right), not the content bottom.
// SafeArea handles left/right insets for the notch.
// Note: landscapeForceVerticalChat uses portrait layout in landscape
// orientation with normal (non-immersive) system UI, so it still needs
// bottom padding.
final isHorizontalLandscape =
context.isLandscape &&
!chatStore.settings.landscapeForceVerticalChat;
final needsBottomPadding =
!chatStore.assetsStore.showEmoteMenu && !isHorizontalLandscape;
return isFullscreenOverlay
? Padding(
padding: EdgeInsets.only(
bottom: chatStore.assetsStore.showEmoteMenu
? 0
: MediaQuery.of(context).padding.bottom,
bottom: needsBottomPadding
? MediaQuery.of(context).padding.bottom
: 0,
),
child: bottomBarContent,
)
: BlurredContainer(
gradientDirection: GradientDirection.down,
padding: EdgeInsets.only(
bottom: chatStore.assetsStore.showEmoteMenu
? 0
: MediaQuery.of(context).padding.bottom,
bottom: needsBottomPadding
? MediaQuery.of(context).padding.bottom
: 0,
),
child: bottomBarContent,
);