Skip to content

fix: 🐛 ensure images are properly added to preview when sending messages with text#430

Open
japanshah-simform wants to merge 1 commit into
mainfrom
fix/handle-image-selection
Open

fix: 🐛 ensure images are properly added to preview when sending messages with text#430
japanshah-simform wants to merge 1 commit into
mainfrom
fix/handle-image-selection

Conversation

@japanshah-simform
Copy link
Copy Markdown
Contributor

@japanshah-simform japanshah-simform commented Jan 30, 2026

Description

Before:

Screen.Recording.2026-01-30.at.2.44.17.PM.mov

After:

Simulator.Screen.Recording.-.iPhone.16.Pro.-.2026-05-15.at.12.mp4

Checklist

  • The title of my PR starts with a Conventional Commit prefix (fix:, feat:, docs: etc).
  • I have followed the Contributor Guide when preparing my PR.
  • I have updated/added tests for ALL new/updated/fixed functionality.
  • I have updated/added relevant documentation in docs and added dartdoc comments with ///.
  • I have updated/added relevant examples in examples or docs.

Breaking Change?

  • Yes, this PR is a breaking change.
  • No, this PR is not a breaking change.

Related Issues

@japanshah-simform japanshah-simform force-pushed the fix/handle-image-selection branch from 7b71d96 to d6674e8 Compare January 30, 2026 09:01
@japanshah-simform japanshah-simform self-assigned this Jan 30, 2026
@japanshah-simform japanshah-simform force-pushed the fix/handle-image-selection branch from d6674e8 to 761c6c3 Compare January 30, 2026 09:04
@japanshah-simform japanshah-simform changed the title Handle Image Selection fix: 🐛 ensure images are properly added to preview when sending messages with text Jan 30, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 shouldSendImageWithText in 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.

Comment thread CHANGELOG.md Outdated
Comment on lines +4 to +5
ChatView.handleImageSelection to use shouldSendImageWithText
parameter with custom trailing actions.
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.”

Suggested change
ChatView.handleImageSelection to use shouldSendImageWithText
parameter with custom trailing actions.
`ChatView.handleImageSelection` to support `shouldSendImageWithText`
when using custom `trailingActions`.

Copilot uses AI. Check for mistakes.
Comment on lines 180 to 182
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);
},
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copilot uses AI. Check for mistakes.
Comment on lines +273 to +283
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, '');
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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, '');

Copilot uses AI. Check for mistakes.
Comment thread doc/documentation.md Outdated
Comment on lines +1160 to +1169
trailingActions: (context, controller) => [
GalleryActionButton(
icon: Icon(
Icons.photo_rounded,
size: 30,
color: _theme.iconColor,
),
onPressed: (path, replyMessage) {
ChatView.handleImageSelection(context, path!);
},
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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!);
},
),
],

Copilot uses AI. Check for mistakes.
Comment thread doc/documentation.md Outdated
Comment on lines +1162 to +1170
icon: Icon(
Icons.photo_rounded,
size: 30,
color: _theme.iconColor,
),
onPressed: (path, replyMessage) {
ChatView.handleImageSelection(context, path!);
},
),
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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!);
},
),
],

Copilot uses AI. Check for mistakes.
Comment thread doc/documentation.md Outdated
color: _theme.iconColor,
),
onPressed: (path, replyMessage) {
ChatView.handleImageSelection(context, path!);
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
ChatView.handleImageSelection(context, path!);
if (path != null && path.isNotEmpty) {
ChatView.handleImageSelection(context, path);
}

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.

Comment on lines +178 to +179
onImageSelected: (imagePath, _) {
_onImageSelected(imagePath, '');
///
/// Displays the selected image full-screen with:
/// - A close button at the top-left
/// - An chat name in the top bar
Comment thread example/lib/main.dart Outdated
onSend: (imagePath, caption, reply) {
_chatController.addMessage(
Message(
id: '${DateTime.now().microsecondsSinceEpoch}_img',
Comment thread example/lib/main.dart Outdated
if (caption.isNotEmpty) {
_chatController.addMessage(
Message(
id: '${DateTime.now().microsecondsSinceEpoch}_cap',
Comment thread CHANGELOG.md Outdated
Comment on lines +4 to +6
`shouldSendImageWithText` parameter. Images are now sent through an image preview screen in example that
supports optional text captions. Use `GalleryActionButton` with a custom preview handler to
achieve similar functionality.
Comment thread doc/documentation.md
Comment on lines +1156 to 1157
You can customize the view for sending images by using the `GalleryActionButton` in `trailingActions`. Here's a practical example that opens an image preview screen before sending:

@japanshah-simform japanshah-simform force-pushed the fix/handle-image-selection branch from b6566fc to f5c40d8 Compare May 15, 2026 09:17
children: [
Positioned.fill(
child: InteractiveViewer(
minScale: 0.8,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any specific requirement for keeping minScale at 0.8 here? Allowing the image to shrink below its initial size may not be necessary for the preview screen.

maxScale: 4.0,
child: Center(
child: Image.file(
File(widget.imagePath),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image.file(File(...)) crashes on Flutter Web because dart:io is unsupported. Please take care of web compatibility here as well.

}

void _onImageSelected(String imagePath, String error) {
void _onImageSelected(String imagePath, String messageId) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

messageId is added as a parameter but is never used inside the method body. Please remove the unnecessary parameter if it is not needed.

Comment thread example/lib/main.dart
chatName: widget.chat.name,
onSend: (imagePath, caption, reply) {
var timeStamp =
DateTime.now().microsecondsSinceEpoch;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

timeStamp is never reassigned after initialisation, so final would be more appropriate here than var.

Comment thread doc/documentation.md

## Send Image With Message
You can send images along with your messages by enabling the `shouldSendImageWithText` flag in `sendMessageConfig` all the other things will be handled by the package itself. Here's how to do it:
## Send Images
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The section title Send Images feels a bit too generic now. Since this flow also includes a preview screen and optional caption handling, a more descriptive title may improve clarity in the documentation.

Comment thread doc/documentation.md
chatName: widget.chat.name,
onSend: (imagePath, caption, reply) {
// Create a timestamp for unique message IDs
var timeStamp = DateTime.now().microsecondsSinceEpoch;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^^

@japanshah-simform japanshah-simform force-pushed the fix/handle-image-selection branch from f5c40d8 to 307d0a7 Compare May 15, 2026 12:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants