fix autocomplete bar blocking bottom of chat
This commit is contained in:
parent
bd194e91c2
commit
4a9678bb15
4 changed files with 79 additions and 29 deletions
|
|
@ -58,7 +58,7 @@ class Chat extends StatelessWidget {
|
|||
padding: EdgeInsets.only(
|
||||
top: MediaQuery.of(context).padding.top,
|
||||
bottom:
|
||||
68 +
|
||||
chatStore.bottomBarHeight +
|
||||
(chatStore.assetsStore.showEmoteMenu
|
||||
? 0
|
||||
: MediaQuery.of(context).padding.bottom),
|
||||
|
|
@ -70,7 +70,7 @@ class Chat extends StatelessWidget {
|
|||
padding: (listPadding ?? EdgeInsets.zero).add(
|
||||
EdgeInsets.only(
|
||||
bottom:
|
||||
68 +
|
||||
chatStore.bottomBarHeight +
|
||||
(chatStore.assetsStore.showEmoteMenu
|
||||
? 0
|
||||
: MediaQuery.of(
|
||||
|
|
@ -126,7 +126,7 @@ class Chat extends StatelessWidget {
|
|||
top: 4,
|
||||
right: 4,
|
||||
bottom:
|
||||
68 +
|
||||
chatStore.bottomBarHeight +
|
||||
(chatStore.assetsStore.showEmoteMenu
|
||||
? 0
|
||||
: MediaQuery.of(context).padding.bottom),
|
||||
|
|
|
|||
|
|
@ -36,6 +36,12 @@ abstract class ChatStoreBase with Store {
|
|||
'ROOMSTATE',
|
||||
};
|
||||
|
||||
/// Base height of the bottom bar (input field area).
|
||||
static const _baseBottomBarHeight = 68.0;
|
||||
|
||||
/// Height of the autocomplete bar (SizedBox + Divider).
|
||||
static const _autocompleteHeight = 51.0;
|
||||
|
||||
/// Checks if IRC data contains a command that should bypass the chat delay.
|
||||
/// Returns true if any message in the data contains a bypass command.
|
||||
bool _shouldBypassDelay(String data) {
|
||||
|
|
@ -203,6 +209,47 @@ abstract class ChatStoreBase with Store {
|
|||
/// Public getter for whether the chat is in shared chat mode.
|
||||
bool get isInSharedChatMode => _isInSharedChatMode;
|
||||
|
||||
/// Emotes matching the current autocomplete search term.
|
||||
@computed
|
||||
List<Emote> get matchingEmotes {
|
||||
if (!_showEmoteAutocomplete) return const [];
|
||||
final searchTerm = _inputText.split(' ').last.toLowerCase();
|
||||
if (searchTerm.isEmpty) return const [];
|
||||
|
||||
return [
|
||||
...assetsStore.userEmoteToObject.values,
|
||||
...assetsStore.bttvEmotes,
|
||||
...assetsStore.ffzEmotes,
|
||||
...assetsStore.sevenTVEmotes,
|
||||
].where((emote) => emote.name.toLowerCase().contains(searchTerm)).toList();
|
||||
}
|
||||
|
||||
/// Chatters matching the current mention autocomplete search term.
|
||||
@computed
|
||||
List<String> get matchingChatters {
|
||||
if (!_showMentionAutocomplete) return const [];
|
||||
final searchTerm =
|
||||
_inputText.split(' ').last.replaceFirst('@', '').toLowerCase();
|
||||
return chatDetailsStore.chatUsers
|
||||
.where((chatter) => chatter.contains(searchTerm))
|
||||
.toList();
|
||||
}
|
||||
|
||||
/// Current bottom bar height based on visible overlays.
|
||||
/// Used to dynamically adjust chat message list padding.
|
||||
@computed
|
||||
double get bottomBarHeight {
|
||||
var height = _baseBottomBarHeight;
|
||||
|
||||
if (settings.autocomplete &&
|
||||
((_showEmoteAutocomplete && matchingEmotes.isNotEmpty) ||
|
||||
(_showMentionAutocomplete && matchingChatters.isNotEmpty))) {
|
||||
height += _autocompleteHeight;
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
ChatStoreBase({
|
||||
required this.twitchApi,
|
||||
required this.auth,
|
||||
|
|
|
|||
|
|
@ -17,6 +17,29 @@ mixin _$ChatStore on ChatStoreBase, Store {
|
|||
() => super.renderMessages,
|
||||
name: 'ChatStoreBase.renderMessages',
|
||||
)).value;
|
||||
Computed<List<Emote>>? _$matchingEmotesComputed;
|
||||
|
||||
@override
|
||||
List<Emote> get matchingEmotes =>
|
||||
(_$matchingEmotesComputed ??= Computed<List<Emote>>(
|
||||
() => super.matchingEmotes,
|
||||
name: 'ChatStoreBase.matchingEmotes',
|
||||
)).value;
|
||||
Computed<List<String>>? _$matchingChattersComputed;
|
||||
|
||||
@override
|
||||
List<String> get matchingChatters =>
|
||||
(_$matchingChattersComputed ??= Computed<List<String>>(
|
||||
() => super.matchingChatters,
|
||||
name: 'ChatStoreBase.matchingChatters',
|
||||
)).value;
|
||||
Computed<double>? _$bottomBarHeightComputed;
|
||||
|
||||
@override
|
||||
double get bottomBarHeight => (_$bottomBarHeightComputed ??= Computed<double>(
|
||||
() => super.bottomBarHeight,
|
||||
name: 'ChatStoreBase.bottomBarHeight',
|
||||
)).value;
|
||||
|
||||
late final _$timeRemainingAtom = Atom(
|
||||
name: 'ChatStoreBase.timeRemaining',
|
||||
|
|
@ -489,7 +512,10 @@ mixin _$ChatStore on ChatStoreBase, Store {
|
|||
timeRemaining: ${timeRemaining},
|
||||
expandChat: ${expandChat},
|
||||
replyingToMessage: ${replyingToMessage},
|
||||
renderMessages: ${renderMessages}
|
||||
renderMessages: ${renderMessages},
|
||||
matchingEmotes: ${matchingEmotes},
|
||||
matchingChatters: ${matchingChatters},
|
||||
bottomBarHeight: ${bottomBarHeight}
|
||||
''';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,31 +57,8 @@ class ChatBottomBar extends StatelessWidget {
|
|||
|
||||
return Observer(
|
||||
builder: (context) {
|
||||
final matchingEmotes =
|
||||
[
|
||||
...chatStore.assetsStore.userEmoteToObject.values,
|
||||
...chatStore.assetsStore.bttvEmotes,
|
||||
...chatStore.assetsStore.ffzEmotes,
|
||||
...chatStore.assetsStore.sevenTVEmotes,
|
||||
]
|
||||
.where(
|
||||
(emote) => emote.name.toLowerCase().contains(
|
||||
chatStore.inputText.split(' ').last.toLowerCase(),
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
|
||||
final matchingChatters = chatStore.chatDetailsStore.chatUsers
|
||||
.where(
|
||||
(chatter) => chatter.contains(
|
||||
chatStore.inputText
|
||||
.split(' ')
|
||||
.last
|
||||
.replaceFirst('@', '')
|
||||
.toLowerCase(),
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
final matchingEmotes = chatStore.matchingEmotes;
|
||||
final matchingChatters = chatStore.matchingChatters;
|
||||
|
||||
final isFullscreenOverlay =
|
||||
chatStore.settings.fullScreen && context.isLandscape;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue