Improve design of message view text input

This commit is contained in:
Nutcake 2023-05-16 10:51:55 +02:00
parent 2b7b4e2dba
commit 3fcb9b7a49
2 changed files with 71 additions and 46 deletions

View file

@ -25,7 +25,7 @@ class MessageBubble extends StatelessWidget {
Material( Material(
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
color: backgroundColor, color: backgroundColor,
textStyle: Theme.of(context).textTheme.bodyMedium?.copyWith(color: foregroundColor), textStyle: Theme.of(context).textTheme.bodySmall?.copyWith(color: foregroundColor),
child: Container( child: Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8), padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
child: switch (message.type) { child: switch (message.type) {

View file

@ -18,13 +18,14 @@ class MessagesList extends StatefulWidget {
State<StatefulWidget> createState() => _MessagesListState(); State<StatefulWidget> createState() => _MessagesListState();
} }
class _MessagesListState extends State<MessagesList> { class _MessagesListState extends State<MessagesList> with SingleTickerProviderStateMixin {
final TextEditingController _messageTextController = TextEditingController(); final TextEditingController _messageTextController = TextEditingController();
final ScrollController _sessionListScrollController = ScrollController(); final ScrollController _sessionListScrollController = ScrollController();
final ScrollController _messageScrollController = ScrollController(); final ScrollController _messageScrollController = ScrollController();
bool _isSendable = false; bool _isSendable = false;
bool _showSessionListScrollChevron = false; bool _showSessionListScrollChevron = false;
bool _showBottomBarShadow = false;
double get _shevronOpacity => _showSessionListScrollChevron ? 1.0 : 0.0; double get _shevronOpacity => _showSessionListScrollChevron ? 1.0 : 0.0;
@ -52,6 +53,19 @@ class _MessagesListState extends State<MessagesList> {
}); });
} }
}); });
_messageScrollController.addListener(() {
if (!_messageScrollController.hasClients) return;
if (_messageScrollController.position.atEdge && _messageScrollController.position.pixels == 0 &&
_showBottomBarShadow) {
setState(() {
_showBottomBarShadow = false;
});
} else if (!_showBottomBarShadow) {
setState(() {
_showBottomBarShadow = true;
});
}
});
} }
@override @override
@ -74,7 +88,11 @@ class _MessagesListState extends State<MessagesList> {
Text(widget.friend.username), Text(widget.friend.username),
if (widget.friend.isHeadless) Padding( if (widget.friend.isHeadless) Padding(
padding: const EdgeInsets.only(left: 12), padding: const EdgeInsets.only(left: 12),
child: Icon(Icons.dns, size: 18, color: Theme.of(context).colorScheme.onSecondaryContainer.withAlpha(150),), child: Icon(Icons.dns, size: 18, color: Theme
.of(context)
.colorScheme
.onSecondaryContainer
.withAlpha(150),),
), ),
], ],
), ),
@ -177,49 +195,57 @@ class _MessagesListState extends State<MessagesList> {
), ),
], ],
), ),
bottomNavigationBar: Padding( bottomNavigationBar: AnimatedContainer(
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
blurRadius: _showBottomBarShadow ? 8 : 0,
color: Theme.of(context).shadowColor,
offset: const Offset(0, 4),
),
],
color: Theme.of(context).colorScheme.background,
),
padding: MediaQuery padding: MediaQuery
.of(context) .of(context)
.viewInsets, .viewInsets + const EdgeInsets.symmetric(horizontal: 4),
child: BottomAppBar( duration: const Duration(milliseconds: 250),
elevation: 0.0, child: Row(
padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 6), children: [
child: Row( Expanded(
children: [ child: Padding(
Expanded( padding: const EdgeInsets.all(8),
child: Padding( child: TextField(
padding: const EdgeInsets.all(8), autocorrect: true,
child: TextField( controller: _messageTextController,
autocorrect: true, maxLines: 4,
controller: _messageTextController, minLines: 1,
maxLines: 4, onChanged: (text) {
minLines: 1, if (text.isNotEmpty && !_isSendable) {
onChanged: (text) { setState(() {
if (text.isNotEmpty && !_isSendable) { _isSendable = true;
setState(() { });
_isSendable = true; } else if (text.isEmpty && _isSendable) {
}); setState(() {
} else if (text.isEmpty && _isSendable) { _isSendable = false;
setState(() { });
_isSendable = false; }
}); },
} decoration: InputDecoration(
}, isDense: true,
decoration: InputDecoration( hintText: "Send a message to ${widget.friend
isDense: true, .username}...",
hintText: "Send a message to ${widget.friend contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
.username}...", border: OutlineInputBorder(
contentPadding: const EdgeInsets.all(16), borderRadius: BorderRadius.circular(24)
border: OutlineInputBorder( )
borderRadius: BorderRadius.circular(24)
)
),
), ),
), ),
), ),
Padding( ),
padding: const EdgeInsets.only(left: 8, right: 4.0), Padding(
child: Consumer<MessagingClient>( padding: const EdgeInsets.only(left: 8, right: 4.0),
child: Consumer<MessagingClient>(
builder: (context, mClient, _) { builder: (context, mClient, _) {
return IconButton( return IconButton(
splashRadius: 24, splashRadius: 24,
@ -255,11 +281,10 @@ class _MessagesListState extends State<MessagesList> {
iconSize: 28, iconSize: 28,
icon: const Icon(Icons.send), icon: const Icon(Icons.send),
); );
} },
), ),
) )
], ],
),
), ),
), ),
); );