fix: 🐛 ensure images are properly added to preview when sending messages with text#430
fix: 🐛 ensure images are properly added to preview when sending messages with text#430japanshah-simform wants to merge 1 commit intomainfrom
Conversation
7b71d96 to
d6674e8
Compare
d6674e8 to
761c6c3
Compare
There was a problem hiding this comment.
Pull request overview
Fixes image-preview behavior when shouldSendImageWithText is enabled by providing a public API to programmatically add selected images into the SendMessageWidget preview (useful for custom trailing actions).
Changes:
- Refactors SendMessageWidget image-selection logic into
handleImageSelection. - Adds
ChatView.handleImageSelection(context, imagePath)for external/custom action buttons to add images to the preview. - Updates the example and docs to demonstrate the new workflow and enables
shouldSendImageWithTextin the sample.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| lib/src/widgets/send_message_widget.dart | Extracts image-selection/preview logic into handleImageSelection and routes onImageSelected through it. |
| lib/src/widgets/chat_view.dart | Adds a static helper to forward image selection into the SendMessageWidget state. |
| example/lib/main.dart | Demonstrates adding an image to the preview via ChatView.handleImageSelection. |
| doc/documentation.md | Updates guidance for sending images with text and using the new API (currently contains invalid snippet). |
| CHANGELOG.md | Adds an unreleased changelog entry for the new fix/API. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ChatView.handleImageSelection to use shouldSendImageWithText | ||
| parameter with custom trailing actions. |
There was a problem hiding this comment.
Changelog entry wording is a bit unclear/grammatically awkward (“Added … to use … parameter …”). Consider rephrasing to something like: “Added ChatView.handleImageSelection to support shouldSendImageWithText when using custom trailingActions.”
| ChatView.handleImageSelection to use shouldSendImageWithText | |
| parameter with custom trailing actions. | |
| `ChatView.handleImageSelection` to support `shouldSendImageWithText` | |
| when using custom `trailingActions`. |
| onImageSelected: (images, messageId) { | ||
| if (widget.sendMessageConfig | ||
| .shouldSendImageWithText) { | ||
| if (images.isNotEmpty) { | ||
| _selectedImageViewWidgetKey.currentState | ||
| ?.selectedImages.value = [ | ||
| ...?_selectedImageViewWidgetKey | ||
| .currentState?.selectedImages.value, | ||
| images | ||
| ]; | ||
|
|
||
| FocusScope.of(context) | ||
| .requestFocus(_focusNode); | ||
| } | ||
| } else { | ||
| _onImageSelected(images, ''); | ||
| } | ||
| handleImageSelection(images); | ||
| }, |
There was a problem hiding this comment.
The onImageSelected callback parameter messageId is unused, which triggers the unused_parameter analyzer warning unless it’s named _. Consider changing the callback signature to (imagePath, _) (and renaming images to imagePath for clarity) before calling handleImageSelection(imagePath).
| void handleImageSelection(String images) { | ||
| if (widget.sendMessageConfig.shouldSendImageWithText) { | ||
| if (images.isNotEmpty) { | ||
| _selectedImageViewWidgetKey.currentState?.selectedImages.value = [ | ||
| ...?_selectedImageViewWidgetKey.currentState?.selectedImages.value, | ||
| images | ||
| ]; | ||
| FocusScope.of(context).requestFocus(_focusNode); | ||
| } | ||
| } else { | ||
| _onImageSelected(images, ''); |
There was a problem hiding this comment.
handleImageSelection takes a single image path, but the parameter is named images, which is misleading given the surrounding code uses a list of selected images. Renaming the parameter to imagePath (and updating internal references) would reduce confusion.
| void handleImageSelection(String images) { | |
| if (widget.sendMessageConfig.shouldSendImageWithText) { | |
| if (images.isNotEmpty) { | |
| _selectedImageViewWidgetKey.currentState?.selectedImages.value = [ | |
| ...?_selectedImageViewWidgetKey.currentState?.selectedImages.value, | |
| images | |
| ]; | |
| FocusScope.of(context).requestFocus(_focusNode); | |
| } | |
| } else { | |
| _onImageSelected(images, ''); | |
| void handleImageSelection(String imagePath) { | |
| if (widget.sendMessageConfig.shouldSendImageWithText) { | |
| if (imagePath.isNotEmpty) { | |
| _selectedImageViewWidgetKey.currentState?.selectedImages.value = [ | |
| ...?_selectedImageViewWidgetKey.currentState?.selectedImages.value, | |
| imagePath | |
| ]; | |
| FocusScope.of(context).requestFocus(_focusNode); | |
| } | |
| } else { | |
| _onImageSelected(imagePath, ''); |
| trailingActions: (context, controller) => [ | ||
| GalleryActionButton( | ||
| icon: Icon( | ||
| Icons.photo_rounded, | ||
| size: 30, | ||
| color: _theme.iconColor, | ||
| ), | ||
| onPressed: (path, replyMessage) { | ||
| ChatView.handleImageSelection(context, path!); | ||
| }, |
There was a problem hiding this comment.
The documentation example is using trailingActions directly on SendMessageConfiguration, but that property is on TextFieldConfiguration (sendMessageConfig.textFieldConfig.trailingActions). As written, the snippet won’t compile and may mislead users.
| trailingActions: (context, controller) => [ | |
| GalleryActionButton( | |
| icon: Icon( | |
| Icons.photo_rounded, | |
| size: 30, | |
| color: _theme.iconColor, | |
| ), | |
| onPressed: (path, replyMessage) { | |
| ChatView.handleImageSelection(context, path!); | |
| }, | |
| textFieldConfig: TextFieldConfiguration( | |
| trailingActions: (context, controller) => [ | |
| GalleryActionButton( | |
| icon: Icon( | |
| Icons.photo_rounded, | |
| size: 30, | |
| color: _theme.iconColor, | |
| ), | |
| onPressed: (path, replyMessage) { | |
| ChatView.handleImageSelection(context, path!); | |
| }, | |
| ), | |
| ], |
| icon: Icon( | ||
| Icons.photo_rounded, | ||
| size: 30, | ||
| color: _theme.iconColor, | ||
| ), | ||
| onPressed: (path, replyMessage) { | ||
| ChatView.handleImageSelection(context, path!); | ||
| }, | ||
| ), |
There was a problem hiding this comment.
The GalleryActionButton snippet in this code block has mismatched indentation/parentheses and is missing the closing ] / ) needed to end trailingActions and SendMessageConfiguration, so the example won’t compile as-is. Please fix the bracket/parenthesis structure so the snippet is valid Dart.
| icon: Icon( | |
| Icons.photo_rounded, | |
| size: 30, | |
| color: _theme.iconColor, | |
| ), | |
| onPressed: (path, replyMessage) { | |
| ChatView.handleImageSelection(context, path!); | |
| }, | |
| ), | |
| icon: Icon( | |
| Icons.photo_rounded, | |
| size: 30, | |
| color: _theme.iconColor, | |
| ), | |
| onPressed: (path, replyMessage) { | |
| ChatView.handleImageSelection(context, path!); | |
| }, | |
| ), | |
| ], |
| color: _theme.iconColor, | ||
| ), | ||
| onPressed: (path, replyMessage) { | ||
| ChatView.handleImageSelection(context, path!); |
There was a problem hiding this comment.
The example calls ChatView.handleImageSelection(context, path!) without guarding for path == null (e.g., user cancels picker). Since path is nullable in the action callbacks, the docs should show a null/empty check (as in the example app) to avoid runtime exceptions.
| ChatView.handleImageSelection(context, path!); | |
| if (path != null && path.isNotEmpty) { | |
| ChatView.handleImageSelection(context, path); | |
| } |
Description
Before:
Screen.Recording.2026-01-30.at.2.44.17.PM.mov
After:
Screen.Recording.2026-01-30.at.2.44.50.PM.mov
Checklist
fix:,feat:,docs:etc).docsand added dartdoc comments with///.examplesordocs.Breaking Change?
Related Issues