fix: clean up messages composer bar

ref:
This commit is contained in:
Janez T
2026-03-06 14:11:36 +01:00
parent a9d062dc34
commit f6779e8776

View File

@@ -287,61 +287,6 @@ class _MessagesTabState extends State<MessagesTab> {
return 'Select recipient'; return 'Select recipient';
} }
String _getCurrentScopeLabel() {
if (_destinationType ==
MessageDestinationPreferences.destinationTypeChannel) {
final channelName =
_selectedRecipient?.getLocalizedDisplayName(context) ??
AppLocalizations.of(context)!.publicChannel;
return 'Channel > $channelName';
}
if (_destinationType == MessageDestinationPreferences.destinationTypeRoom) {
final roomName =
_selectedRecipient?.displayName ??
AppLocalizations.of(context)!.messages;
return 'Room > $roomName';
}
final contactName =
_selectedRecipient?.displayName ??
AppLocalizations.of(context)!.messages;
return 'Direct > $contactName';
}
Widget _buildScopeIndicator() {
final theme = Theme.of(context);
return SizedBox(
width: double.infinity,
child: Align(
alignment: Alignment.centerLeft,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
Icons.visibility_outlined,
size: 14,
color: theme.colorScheme.onSurfaceVariant,
),
const SizedBox(width: 6),
Flexible(
child: Text(
'View: ${_getCurrentScopeLabel()}',
maxLines: 1,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: theme.textTheme.labelSmall?.copyWith(
color: theme.colorScheme.onSurfaceVariant,
),
),
),
],
),
),
);
}
Future<void> _sendMessage() async { Future<void> _sendMessage() async {
final text = _textController.text.trim(); final text = _textController.text.trim();
if (text.isEmpty) return; if (text.isEmpty) return;
@@ -1622,7 +1567,7 @@ class _MessagesTabState extends State<MessagesTab> {
vertical: 8, vertical: 8,
), ),
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
// Quick actions (+) button // Quick actions (+) button
IconButton( IconButton(
@@ -1672,114 +1617,126 @@ class _MessagesTabState extends State<MessagesTab> {
), ),
), ),
const SizedBox(width: 4), const SizedBox(width: 4),
// Scope label + text field share the same alignment
Expanded( Expanded(
child: Column( child: TextField(
mainAxisSize: MainAxisSize.min, controller: _textController,
crossAxisAlignment: CrossAxisAlignment.start, focusNode: _focusNode,
children: [ maxLength: _maxCharacters,
Padding( maxLines: null,
padding: const EdgeInsets.only( maxLengthEnforcement: MaxLengthEnforcement.enforced,
left: 4, style: const TextStyle(fontSize: 14),
right: 4, decoration: InputDecoration(
bottom: 6, hintText: AppLocalizations.of(
), context,
child: _buildScopeIndicator(), )!.typeYourMessage,
hintStyle: const TextStyle(fontSize: 14),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(24),
), ),
TextField( contentPadding: const EdgeInsets.symmetric(
controller: _textController, horizontal: 16,
focusNode: _focusNode, vertical: 10,
maxLength: _maxCharacters, ),
maxLines: null, isDense: true,
maxLengthEnforcement: counterText: _characterCount >= 150
MaxLengthEnforcement.enforced, ? '$_characterCount/$_maxCharacters'
style: const TextStyle(fontSize: 14), : '',
decoration: InputDecoration( counterStyle: TextStyle(
hintText: AppLocalizations.of( fontSize: 10,
context, color: _characterCount > _maxCharacters * 0.9
)!.typeYourMessage, ? Colors.orange
hintStyle: const TextStyle(fontSize: 14), : Theme.of(
border: OutlineInputBorder( context,
borderRadius: BorderRadius.circular(24), ).textTheme.bodySmall?.color,
), ),
contentPadding: const EdgeInsets.symmetric( suffixIcon: Builder(
horizontal: 16, builder: (context) {
vertical: 10, final canSendText =
), !_isRecording &&
isDense: true, !_isSendingVoice &&
counterText: _characterCount >= 150 _textController.text.trim().isNotEmpty;
? '$_characterCount/$_maxCharacters' final semanticsLabel = _isRecording
: '', ? 'Recording... release to send voice'
counterStyle: TextStyle( : (_isSendingVoice
fontSize: 10, ? 'Sending voice...'
color: : _voiceSupported
_characterCount > _maxCharacters * 0.9 ? 'Send (long press to record voice)'
? Colors.orange : 'Send');
: Theme.of(
context, return Semantics(
).textTheme.bodySmall?.color, button: true,
), enabled:
suffixIcon: GestureDetector( canSendText ||
onLongPressStart: (_voiceSupported && !_isSendingVoice),
label: semanticsLabel,
onTap: canSendText ? _sendMessage : null,
onLongPress:
(_voiceSupported && !_isSendingVoice) (_voiceSupported && !_isSendingVoice)
? (_) => _startVoiceRecording() ? () {
if (_isRecording) {
_stopAndSendVoice();
return;
}
_startVoiceRecording();
}
: null, : null,
onLongPressEnd: child: Tooltip(
(_voiceSupported && _isRecording) message: semanticsLabel,
? (_) => _stopAndSendVoice() excludeFromSemantics: true,
: null, child: GestureDetector(
onLongPressCancel: excludeFromSemantics: true,
(_voiceSupported && _isRecording) onLongPressStart:
? () => _stopAndSendVoice() (_voiceSupported &&
: null, !_isSendingVoice)
child: IconButton( ? (_) => _startVoiceRecording()
icon: _isSendingVoice : null,
? const SizedBox( onLongPressEnd:
width: 18, (_voiceSupported && _isRecording)
height: 18, ? (_) => _stopAndSendVoice()
child: CircularProgressIndicator( : null,
strokeWidth: 2, onLongPressCancel:
), (_voiceSupported && _isRecording)
) ? () => _stopAndSendVoice()
: Icon( : null,
_isRecording child: IconButton(
? Icons.mic icon: _isSendingVoice
: Icons.send_rounded, ? const SizedBox(
size: 22, width: 18,
color: _isRecording height: 18,
? Colors.red child:
: (_textController.text CircularProgressIndicator(
.trim() strokeWidth: 2,
.isEmpty ),
? Theme.of( )
context, : Icon(
).disabledColor _isRecording
: Theme.of(context) ? Icons.mic
.colorScheme : Icons.send_rounded,
.primary), size: 22,
), color: _isRecording
onPressed: ? Colors.red
_isRecording || : (_textController.text
_isSendingVoice || .trim()
_textController.text .isEmpty
.trim() ? Theme.of(
.isEmpty context,
? null ).disabledColor
: _sendMessage, : Theme.of(context)
tooltip: _isRecording .colorScheme
? 'Recording... release to send voice' .primary),
: (_isSendingVoice ),
? 'Sending voice...' onPressed: canSendText
: _voiceSupported ? _sendMessage
? 'Send (long press to record voice)' : null,
: 'Send'), ),
),
), ),
), );
), },
textInputAction: TextInputAction.send,
onSubmitted: (_) => _sendMessage(),
), ),
], ),
textInputAction: TextInputAction.send,
onSubmitted: (_) => _sendMessage(),
), ),
), ),
], ],