feat(chat): prevent duplicate paste image context menu options

This commit is contained in:
cogwheel
2025-12-21 08:55:25 +05:30
parent 9e7b923dd9
commit b6f97b1a1c

View File

@@ -319,10 +319,9 @@ class _ModernChatInputState extends ConsumerState<ModernChatInput>
/// Builds a custom context menu with standard options plus "Paste Image". /// Builds a custom context menu with standard options plus "Paste Image".
/// ///
/// The standard paste only works for text. This adds a "Paste Image" /// Adds a "Paste Image" option when there's an image in the clipboard,
/// option that uses the pasteboard package to read images from clipboard /// but only if the system hasn't already provided one (to avoid duplicates
/// on both iOS and Android. The option only appears when there's actually /// on platforms like iOS that may include their own paste image option).
/// an image in the clipboard.
Widget _buildContextMenu( Widget _buildContextMenu(
BuildContext context, BuildContext context,
EditableTextState editableTextState, EditableTextState editableTextState,
@@ -348,6 +347,19 @@ class _ModernChatInputState extends ConsumerState<ModernChatInput>
final hasImage = imageData != null && imageData.isNotEmpty; final hasImage = imageData != null && imageData.isNotEmpty;
if (hasImage) { if (hasImage) {
// Check if the system already provides a paste image option
// (e.g., iOS may include one automatically). Look for any button
// with a label containing "image" (case-insensitive) to avoid
// adding a duplicate.
final pasteImageLabel =
AppLocalizations.of(context)?.pasteImage ?? 'Paste Image';
final alreadyHasPasteImage = buttonItems.any(
(item) =>
item.label != null &&
item.label!.toLowerCase().contains('image'),
);
if (!alreadyHasPasteImage) {
// Find the index of the standard Paste button to insert after it // Find the index of the standard Paste button to insert after it
final pasteIndex = buttonItems.indexWhere( final pasteIndex = buttonItems.indexWhere(
(item) => item.type == ContextMenuButtonType.paste, (item) => item.type == ContextMenuButtonType.paste,
@@ -355,7 +367,7 @@ class _ModernChatInputState extends ConsumerState<ModernChatInput>
// Capture imageData in closure to avoid re-reading clipboard // Capture imageData in closure to avoid re-reading clipboard
final pasteImageItem = ContextMenuButtonItem( final pasteImageItem = ContextMenuButtonItem(
label: AppLocalizations.of(context)?.pasteImage ?? 'Paste Image', label: pasteImageLabel,
onPressed: () { onPressed: () {
// Close the context menu first // Close the context menu first
ContextMenuController.removeAny(); ContextMenuController.removeAny();
@@ -371,6 +383,7 @@ class _ModernChatInputState extends ConsumerState<ModernChatInput>
buttonItems.add(pasteImageItem); buttonItems.add(pasteImageItem);
} }
} }
}
return AdaptiveTextSelectionToolbar.buttonItems( return AdaptiveTextSelectionToolbar.buttonItems(
anchors: editableTextState.contextMenuAnchors, anchors: editableTextState.contextMenuAnchors,
@@ -1621,7 +1634,7 @@ class _ModernChatInputState extends ConsumerState<ModernChatInput>
.toList(), .toList(),
onContentInserted: _handleContentInserted, onContentInserted: _handleContentInserted,
), ),
// Custom context menu with "Paste Image" option for iOS // Custom context menu with "Paste Image" option
contextMenuBuilder: (context, editableTextState) { contextMenuBuilder: (context, editableTextState) {
return _buildContextMenu(context, editableTextState); return _buildContextMenu(context, editableTextState);
}, },