refactor: Improve chat input UI with enhanced microphone icon handling

- Updated the background color logic in the chat input to use a more consistent alpha value based on brightness.
- Simplified the layout of the chat input by removing unnecessary alignment and shadow properties.
- Introduced a new inline microphone icon that activates voice input, improving user interaction.
- Enhanced the overall structure of the chat input widget for better readability and maintainability.
This commit is contained in:
cogwheel0
2025-10-18 15:35:07 +05:30
parent f36ebfd630
commit bb57f91aeb

View File

@@ -802,9 +802,9 @@ class _ModernChatInputState extends ConsumerState<ModernChatInput>
minHeight: TouchTarget.input, minHeight: TouchTarget.input,
), ),
decoration: BoxDecoration( decoration: BoxDecoration(
color: brightness == Brightness.dark color: composerSurface.withValues(
? composerSurface.withValues(alpha: 0.9) alpha: brightness == Brightness.dark ? 0.9 : 0.2,
: context.conduitTheme.surfaceContainer, ),
borderRadius: BorderRadius.circular(AppBorderRadius.round), borderRadius: BorderRadius.circular(AppBorderRadius.round),
border: Border.all( border: Border.all(
color: outlineColor.withValues( color: outlineColor.withValues(
@@ -812,37 +812,28 @@ class _ModernChatInputState extends ConsumerState<ModernChatInput>
), ),
width: BorderWidth.micro, width: BorderWidth.micro,
), ),
boxShadow: <BoxShadow>[
BoxShadow(
color: shellShadowColor.withValues(
alpha: brightness == Brightness.dark ? 0.4 : 0.22,
),
blurRadius: 24,
spreadRadius: -6,
offset: const Offset(0, 12),
),
],
), ),
child: Align( child: Row(
alignment: Alignment.centerLeft, children: [
child: _buildComposerTextField( Expanded(
brightness: brightness, child: _buildComposerTextField(
sendOnEnter: sendOnEnter, brightness: brightness,
placeholderBase: placeholderBase, sendOnEnter: sendOnEnter,
placeholderFocused: placeholderFocused, placeholderBase: placeholderBase,
contentPadding: const EdgeInsets.symmetric( placeholderFocused: placeholderFocused,
vertical: Spacing.xs, contentPadding: const EdgeInsets.symmetric(
vertical: Spacing.xs,
),
isActive: isActive,
),
), ),
isActive: isActive, if (!_hasText && voiceAvailable && !isGenerating)
), _buildInlineMicIcon(voiceAvailable),
],
), ),
), ),
), ),
const SizedBox(width: Spacing.sm), const SizedBox(width: Spacing.sm),
if (!_hasText && voiceAvailable && !isGenerating)
_buildMicButton(voiceAvailable),
if (!_hasText && voiceAvailable && !isGenerating)
const SizedBox(width: Spacing.sm),
_buildPrimaryButton( _buildPrimaryButton(
_hasText, _hasText,
isGenerating, isGenerating,
@@ -1199,7 +1190,6 @@ class _ModernChatInputState extends ConsumerState<ModernChatInput>
const double iconSize = IconSize.large; const double iconSize = IconSize.large;
const double buttonSize = TouchTarget.minimum; const double buttonSize = TouchTarget.minimum;
final Brightness brightness = Theme.of(context).brightness;
final bool isActive = activeColor != null; final bool isActive = activeColor != null;
final Color iconColor = !enabled final Color iconColor = !enabled
@@ -1207,9 +1197,9 @@ class _ModernChatInputState extends ConsumerState<ModernChatInput>
: (activeColor ?? : (activeColor ??
context.conduitTheme.textPrimary.withValues(alpha: Alpha.strong)); context.conduitTheme.textPrimary.withValues(alpha: Alpha.strong));
final Color baseBackground = brightness == Brightness.dark final Brightness brightness = Theme.of(context).brightness;
? context.conduitTheme.surfaceContainerHighest.withValues(alpha: 0.7) final Color baseBackground = context.conduitTheme.inputBackground
: context.conduitTheme.surfaceContainerHighest; .withValues(alpha: brightness == Brightness.dark ? 0.9 : 0.2);
final Color backgroundColor = !enabled final Color backgroundColor = !enabled
? baseBackground.withValues(alpha: Alpha.disabled) ? baseBackground.withValues(alpha: Alpha.disabled)
: isActive : isActive
@@ -1218,14 +1208,6 @@ class _ModernChatInputState extends ConsumerState<ModernChatInput>
final Color borderColor = isActive final Color borderColor = isActive
? context.conduitTheme.buttonPrimary.withValues(alpha: 0.6) ? context.conduitTheme.buttonPrimary.withValues(alpha: 0.6)
: context.conduitTheme.cardBorder.withValues(alpha: 0.45); : context.conduitTheme.cardBorder.withValues(alpha: 0.45);
final BoxShadow buttonShadow = BoxShadow(
color: context.conduitTheme.cardShadow.withValues(
alpha: brightness == Brightness.dark ? 0.36 : 0.18,
),
blurRadius: 18,
spreadRadius: -6,
offset: const Offset(0, 8),
);
return Tooltip( return Tooltip(
message: tooltip, message: tooltip,
@@ -1250,7 +1232,6 @@ class _ModernChatInputState extends ConsumerState<ModernChatInput>
color: backgroundColor, color: backgroundColor,
borderRadius: BorderRadius.circular(AppBorderRadius.round), borderRadius: BorderRadius.circular(AppBorderRadius.round),
border: Border.all(color: borderColor, width: BorderWidth.thin), border: Border.all(color: borderColor, width: BorderWidth.thin),
boxShadow: enabled ? <BoxShadow>[buttonShadow] : const [],
), ),
child: Center( child: Center(
child: Icon(icon, size: iconSize, color: iconColor), child: Icon(icon, size: iconSize, color: iconColor),
@@ -1301,6 +1282,34 @@ class _ModernChatInputState extends ConsumerState<ModernChatInput>
); );
} }
Widget _buildInlineMicIcon(bool voiceAvailable) {
final bool enabledMic = widget.enabled && voiceAvailable;
return Material(
color: Colors.transparent,
child: InkWell(
borderRadius: BorderRadius.circular(AppBorderRadius.circular),
onTap: enabledMic
? () {
HapticFeedback.selectionClick();
_toggleVoice();
}
: null,
child: Padding(
padding: const EdgeInsets.all(Spacing.xs),
child: Icon(
Platform.isIOS ? CupertinoIcons.mic : Icons.mic,
size: IconSize.medium,
color: _isRecording
? context.conduitTheme.buttonPrimary
: context.conduitTheme.textSecondary.withValues(
alpha: enabledMic ? Alpha.strong : Alpha.disabled,
),
),
),
),
);
}
Widget _buildPrimaryButton( Widget _buildPrimaryButton(
bool hasText, bool hasText,
bool isGenerating, bool isGenerating,