Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

compose: Support images from keyboard for Android #1203

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

PIG208
Copy link
Member

@PIG208 PIG208 commented Dec 24, 2024

Preview error message

image

Fixes: #419
Fixes: #1173

@PIG208 PIG208 force-pushed the pr-keyboard branch 3 times, most recently from 89446ec to af8c5b3 Compare December 24, 2024 21:19
Copy link
Collaborator

@chrisbobbe chrisbobbe left a comment

Choose a reason for hiding this comment

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

Exciting! Small question from a quick skim; I know this is still a draft.

Comment on lines 368 to 381
// The data can be empty when the URL is associated with an empty
// resource. See Flutter engine implementation that provides this data:
// https://github.com/flutter/flutter/blob/0ffc4ce00ea7bb912e379adf39354644eab2c17e/engine/src/flutter/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java#L497-L548
Copy link
Collaborator

Choose a reason for hiding this comment

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

This comment is specifically about the case where data ends up being present as an empty array, right? In the code you linked to, I assume that specifically means readStreamFully came up empty in line 531:

https://github.com/flutter/flutter/blob/0ffc4ce00/engine/src/flutter/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java#L531

final byte[] data = this.readStreamFully(is, 64 * 1024);

(Right?)

How about a different case: what could cause data to be null as opposed to present-but-empty? I noticed KeyboardInsertedContent.data is optional. This would be helpful to document upstream there. 🙂

Also, looking around the whole commitContent function you linked to, it looks like there are various unhappy paths there, where the function can't do something desirable and returns false. Like if the Android version is too old. What's the user-facing behavior in those unhappy paths?

Copy link
Member Author

Choose a reason for hiding this comment

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

Having swept through the Java code, I couldn't find other places where data is null and gets passed via a textInputChannel.commitContent call. The link points to the only current non-test call site. The Dart code constructor doesn't have code paths where data is explicitly null either.

data can be empty if (a) the file is empty or (b) there was an IOException during the read. So data should probably be null if there is an error reading it, so that we can handle it properly.


When returning false, no textInputChannel.commitContent call is made and our handler does not get called at all. But the return value is probably read by some part of the Android SDK code: https://developer.android.com/reference/android/view/inputmethod/BaseInputConnection

Default implementation which invokes View.performReceiveContent on the target view if the view allows content insertion; otherwise returns false without any side effects.

true if this request is accepted by the application, whether the request is already handled or still being handled in background, false otherwise.

I assume the behavior is akin to when we do not provide ContentInsertionConfiguration at all. That also results in this method returning false because the allowedMimeTypes default to an empty list. This gives you an OS-specific error message:
image

@PIG208 PIG208 marked this pull request as ready for review December 26, 2024 22:06
@PIG208 PIG208 added the maintainer review PR ready for review by Zulip maintainers label Dec 26, 2024
@PIG208 PIG208 requested a review from chrisbobbe January 22, 2025 18:45
Copy link
Collaborator

@chrisbobbe chrisbobbe left a comment

Choose a reason for hiding this comment

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

Thanks! The implementation and tests look reasonable; some nits below. Could you please post screen recordings, showing both #419 and #1173?

Comment on lines 478 to 479
await enterTopic(tester, narrow: narrow, topic: 'some topic');
await tester.enterText(contentInputFinder, 'see image: ');
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
await enterTopic(tester, narrow: narrow, topic: 'some topic');
await tester.enterText(contentInputFinder, 'see image: ');
await enterTopic(tester, narrow: narrow, topic: 'some topic');
await enterContent(tester, 'see image: ');

// provided by the Android SDK because of an IO exception.
//
// See Flutter engine implementation that prepares this data:
// https://github.com/flutter/flutter/blob/0ffc4ce00ea7bb912e379adf39354644eab2c17e/engine/src/flutter/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java#L497-L548
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: can shorten URL a bit by using just the first 9 characters of the commit ID

Comment on lines 384 to 419
showErrorDialog(
context: context,
title: zulipLocalizations.errorContentNotInsertedTitle,
message: zulipLocalizations.errorContentToInsertIsEmpty);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
showErrorDialog(
context: context,
title: zulipLocalizations.errorContentNotInsertedTitle,
message: zulipLocalizations.errorContentToInsertIsEmpty);
showErrorDialog(context: context,
title: zulipLocalizations.errorContentNotInsertedTitle,
message: zulipLocalizations.errorContentToInsertIsEmpty);

@PIG208
Copy link
Member Author

PIG208 commented Jan 24, 2025

Could you please post screen recordings, showing both #419 and #1173?

Attach from pasting
Screen_Recording_20250124_183348.mp4
Attach from keyboard
Screen_Recording_20250124_183406.mp4

So the test is more realistic.  A side effect of this is that the
content input text field is focused afterwards.

Signed-off-by: Zixuan James Li <[email protected]>
@PIG208
Copy link
Member Author

PIG208 commented Jan 24, 2025

Thanks for the review! I have updated the PR.

@chrisbobbe
Copy link
Collaborator

Thanks! Oh, also: could you check if this feature is available on all Android versions we support, and if it isn't, put a comment somewhere? (I guess with a TODO(android-sdk-<n>) to remove the comment when it becomes unnecessary.)

Otherwise LGTM, marking for Greg's review.

@chrisbobbe chrisbobbe added integration review Added by maintainers when PR may be ready for integration and removed maintainer review PR ready for review by Zulip maintainers labels Jan 24, 2025
@chrisbobbe chrisbobbe assigned gnprice and unassigned chrisbobbe Jan 24, 2025
@chrisbobbe chrisbobbe requested review from gnprice and chrisbobbe and removed request for chrisbobbe January 24, 2025 23:43
@PIG208
Copy link
Member Author

PIG208 commented Jan 25, 2025

Looks like the support requires at least API level 25, which corresponds to Android 7.1:

https://github.com/flutter/flutter/blob/0ffc4ce00ea7bb912e379adf39354644eab2c17e/engine/src/flutter/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java#L498-L500

(image keyboard was added at the same API level)

This is way lower than Android 9, so it should be available on all versions we support.

@chrisbobbe
Copy link
Collaborator

Cool; yeah, if 9 is our min-supported, then there's nothing to do here; a comment won't be needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
integration review Added by maintainers when PR may be ready for integration
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Paste an image into the compose box, on Android android: Support images from keyboard
3 participants