Skip to content

compose_box: Use inline syntax on upload for image and audio#2188

Open
MritunjayTiwari14 wants to merge 2 commits intozulip:mainfrom
MritunjayTiwari14:pr-inline_imageAudio
Open

compose_box: Use inline syntax on upload for image and audio#2188
MritunjayTiwari14 wants to merge 2 commits intozulip:mainfrom
MritunjayTiwari14:pr-inline_imageAudio

Conversation

@MritunjayTiwari14
Copy link
Copy Markdown
Contributor

@MritunjayTiwari14 MritunjayTiwari14 commented Feb 28, 2026

Fixes #2178.
Fixes #2179.

Changes

Image Upload

Before After
before.webm
after.webm

Audio Upload (No visual changes)

Before After
before_audio.webm
after_audio.webm

References

@MritunjayTiwari14 MritunjayTiwari14 marked this pull request as draft March 1, 2026 02:34
@MritunjayTiwari14 MritunjayTiwari14 marked this pull request as ready for review March 1, 2026 02:38
Copilot AI review requested due to automatic review settings March 1, 2026 02:38
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

Updates the compose box’s upload insertion logic to use Zulip’s inline-media Markdown syntax for image/audio uploads, aligning Flutter behavior with recent server/web changes and removing filename captions in rendered media.

Changes:

  • Generate ![]() Markdown for image (and audio) uploads in the compose box, including the “Uploading …” placeholder.
  • Track whether an upload is image/audio so the final replacement uses the correct Markdown syntax.
  • Update unit/widget tests to expect the new syntax for images.

Reviewed changes

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

File Description
lib/widgets/compose_box.dart Switch upload placeholder/final insertion to ![]() for image/* and audio/* MIME types.
lib/model/compose.dart Add inlineImageOrAudio helper for generating ![]() syntax.
test/widgets/compose_box_test.dart Update compose-box widget test expectations for image/GIF uploads to ![]().
test/model/compose_test.dart Update model test to cover inlineImageOrAudio.
Comments suppressed due to low confidence (1)

test/model/compose_test.dart:383

  • This test is still named inlineLink but now also asserts behavior of inlineImageOrAudio, which makes the test intent less clear when it fails. Consider renaming the test (or splitting) so the name matches what it's covering.
  test('inlineLink', () {
    check(inlineLink('CZO', 'https://chat.zulip.org/')).equals('[CZO](https://chat.zulip.org/)');
    check(inlineLink('Uploading file.txt…', '')).equals('[Uploading file.txt…]()');
    check(inlineImageOrAudio('IMG_2488.png', '/user_uploads/2/a3/ucEMyjxk90mcNF0y9rmW5XKO/IMG_2488.png'))
      .equals('![IMG_2488.png](/user_uploads/2/a3/ucEMyjxk90mcNF0y9rmW5XKO/IMG_2488.png)');

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@chrisbobbe
Copy link
Copy Markdown
Collaborator

chrisbobbe commented Mar 4, 2026

From a quick look it looks like this part isn't done:

#2178 (comment)

I would recommend generating this syntax starting with feature level 467 (https://zulip.com/api/message-formatting#changes-to-image-formatting).

We should avoid producing this syntax when it'll look broken because the server is too old to support it.

(Similarly for audio files; I'm not sure if the feature level threshold is the same.)

@MritunjayTiwari14 MritunjayTiwari14 marked this pull request as draft March 4, 2026 09:06
@MritunjayTiwari14 MritunjayTiwari14 marked this pull request as ready for review March 4, 2026 10:49
@MritunjayTiwari14 MritunjayTiwari14 marked this pull request as draft March 4, 2026 14:56
@MritunjayTiwari14 MritunjayTiwari14 marked this pull request as ready for review March 5, 2026 10:32
@MritunjayTiwari14
Copy link
Copy Markdown
Contributor Author

MritunjayTiwari14 commented Mar 5, 2026

Added server-12 TODO's and respective comments with functionality for discarding if the server version is lower than 12, @chrisbobbe PTAL.

For why i marked Audio Inline Syntax support from server-12, please see: #mobile > issue mislabled with server-12 than server-11

@gnprice gnprice added the maintainer review PR ready for review by Zulip maintainers label Mar 5, 2026
Copy link
Copy Markdown
Collaborator

@Khader-1 Khader-1 left a comment

Choose a reason for hiding this comment

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

Thanks @MritunjayTiwari14! a few notes bellow. Additionally, I'd add more test cases:

  • When the server level is below 467, test that image uploads still use []() syntax (not ![]())
  • Widget tests to cover audio files, not just images

@MritunjayTiwari14 MritunjayTiwari14 force-pushed the pr-inline_imageAudio branch 2 times, most recently from 255aef5 to 1a3ec30 Compare March 10, 2026 12:23
@MritunjayTiwari14
Copy link
Copy Markdown
Contributor Author

Thanks, Khader, for the review. Have pushed some changes. Please take a look whenever you get time.

Copy link
Copy Markdown
Collaborator

@Khader-1 Khader-1 left a comment

Choose a reason for hiding this comment

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

Thanks for the revision @MritunjayTiwari14, code changes LGTM aside from one nit bellow, regarding commits structure, I'd consider squashing both of them into a single commit as I think the first one is overly minimal

Finally, a nit on the commit description:
use Fixes: #[issue number] syntax

compose_box: Use inline syntax on upload for image and audio

Fixes: #2178
Fixes: #2179

Previously, we used standard link text for handling uploaded images
and audio. Zulip Server 12.0 (FL-467) introduced support for the standard
CommonMark syntax for image and audio, we must update the Flutter client to match
and generate the \`![]()\` syntax for these file types.

reference:
  https://spec.commonmark.org/0.30/#image-description

With that said, approving, Let's now request your review @rajveermalviya

@MritunjayTiwari14
Copy link
Copy Markdown
Contributor Author

MritunjayTiwari14 commented Mar 13, 2026

Finally, a nit on the commit description: use Fixes: #[issue number] syntax

With that said, approving! Let's now request your review @rajveermalviya

Thanks for the suggestions 🙂, but since recently we have been using a different "Fixes" format, as mentioned by Greg here.

@MritunjayTiwari14
Copy link
Copy Markdown
Contributor Author

@rajveermalviya Waiting for your review on this...

@Khader-1 Khader-1 requested a review from rajveermalviya April 1, 2026 09:00
Copy link
Copy Markdown
Member

@rajveermalviya rajveermalviya left a comment

Choose a reason for hiding this comment

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

Thanks for working on this @MritunjayTiwari14. Comments below.

Comment on lines +396 to +402
test('inlineImageOrAudio with FL<467', () { // TODO(server-12): remove this test
final store = eg.store(account: eg.account(user: eg.selfUser, zulipFeatureLevel: 466),
initialSnapshot: eg.initialSnapshot(zulipFeatureLevel: 466));
check(inlineImageOrAudio('IMG_2488.png', '/user_uploads/2/a3/ucEMyjxk90mcNF0y9rmW5XKO/IMG_2488.png', store: store))
.equals('[IMG_2488.png](/user_uploads/2/a3/ucEMyjxk90mcNF0y9rmW5XKO/IMG_2488.png)');
check(inlineImageOrAudio('foo_bar.mp3', '/user_uploads/2/a3/ucEMyjxk90mcNF0y9rmW5XKO/foo_bar.mp3', store: store))
.equals('[foo_bar.mp3](/user_uploads/2/a3/ucEMyjxk90mcNF0y9rmW5XKO/foo_bar.mp3)');
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't think it sounds correct to name this function inline when it can generate markdown which will not result in image or audio previews rendered inline.

Comment on lines +264 to +273
String inlineImageOrAudio(String visibleText, String destination, {
required PerAccountStore store,
}) {
// While the Audio Inline syntax was introduced in server-11(FL-405),
// it is not recommended for widespread use until 12. Discussion:
// https://chat.zulip.org/#narrow/channel/48-mobile/topic/issue.20mislabled.20with.20server-12.20than.20server-11/with/2398267
// TODO(server-12): simplify and remove comment
return store.zulipFeatureLevel >= 467
? '![$visibleText]($destination)'
: '[$visibleText]($destination)';
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

By following that thread, I see that inline image links should be generated from feature level 467 (as per this message). But do not see any discussion that indicates inline audio previews should be generated from same feature level. Only relevant indication I see is that #2179 is marked with "server-12" label.

Should both inline image and inline audio link generation handled separately?

Copy link
Copy Markdown
Contributor Author

@MritunjayTiwari14 MritunjayTiwari14 Apr 9, 2026

Choose a reason for hiding this comment

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

Good question, it might happen that the inline audio syntax was recommended to use from a different feature level. As I too was not able to find the exact FL for that. I have started discussing that on #api documentation > which FL for inline audio syntax.

…e syntax

Post FL-467, Zulip recommends using the Inline
Markdown  syntax (\`![](...)\`) for images and
audio. We should also add support for that.

To generate the correct inline input syntax in
compose_box, we have defined a helper function
`imageAudioLink`.
Fixes zulip#2178.
Fixes zulip#2179.

Previously, we used standard link text for handling uploaded images
and audio. Zulip Server 12.0 (FL-467) introduced widespread support
for the standard CommonMark (inline) syntax for image and audio.
We must update the Flutter client to match and generate the \`![]()\`
syntax on input for these file types.

We used mime type to capture these types of media, and
process their input syntax using `imageAudioLink`.

note:
- Audio player syntax was introduced in server-11 (FL-405),
but paired up with image input syntax, it was recommended for
widespread use by clients post server-12 (FL-467). For more details
on this, See Api Changelog and this:
  https://chat.zulip.org/#narrow/channel/412-api-documentation/topic/which.20FL.20for.20inline.20audio.20syntax/with/2429954

reference:
  https://spec.commonmark.org/0.30/#image-description
@MritunjayTiwari14
Copy link
Copy Markdown
Contributor Author

I have pushed new changes @rajveermalviya, PTAL.

Difference made since the last round:

  • We don't even need to pass store in registerUploadStart and registerUploadEnd, we can use it without that, since store was already declared and initialized inside the abstract class ComposeController, which is inherited by ComposeContentController.

  • Changed the name of the inlineImageOrAudio function to imageAudioLink for better comprehension. Since we are not using inline, we append Link, which produces a cue that it is a Link.

  • Reproduced the TODO from the image success test as it is, in the newly created audio success test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintainer review PR ready for review by Zulip maintainers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use new inline-media syntax for audio files Use new inline-image syntax on upload

6 participants