Skip to content

Conversation

@MritunjayTiwari14
Copy link
Contributor

@MritunjayTiwari14 MritunjayTiwari14 commented Oct 11, 2025

Fixes #1824

Chat thread:

Design (Outdated)

Before After After(Clicking Button)
b Rclick_b b (2)
w_b w_click_b w_n

Light Theme

XRecorder_20251015_04.mp4

Dark Theme

XRecorder_20251015_05.mp4

@MritunjayTiwari14 MritunjayTiwari14 changed the title compose: Add start video call button in compose compose_box: Add start video call button in compose Oct 12, 2025
@MritunjayTiwari14 MritunjayTiwari14 marked this pull request as ready for review October 12, 2025 10:56
@MritunjayTiwari14 MritunjayTiwari14 force-pushed the issue-1824 branch 3 times, most recently from 5ab42a9 to b2bb501 Compare October 14, 2025 11:22
@gnprice
Copy link
Member

gnprice commented Oct 15, 2025

Thanks. It looks like you still have a TODO item before this is ready to be reviewed, so marking it as draft for now.

@gnprice gnprice marked this pull request as draft October 15, 2025 04:06
@MritunjayTiwari14 MritunjayTiwari14 force-pushed the issue-1824 branch 10 times, most recently from 4cd6e12 to 576234b Compare October 16, 2025 09:42
@MritunjayTiwari14 MritunjayTiwari14 marked this pull request as ready for review October 16, 2025 10:02
@MritunjayTiwari14
Copy link
Contributor Author

All the TODO are done @gnprice!

@gnprice
Copy link
Member

gnprice commented Oct 17, 2025

Thanks. Before this can be reviewed, you'll need to revise it to have clear and coherent commits. See the instructions we discussed on a previous PR thread: #1830 (review)

@MritunjayTiwari14 MritunjayTiwari14 force-pushed the issue-1824 branch 7 times, most recently from e6835e8 to 8a417e9 Compare October 18, 2025 06:11
@MritunjayTiwari14
Copy link
Contributor Author

Thanks @gnprice for suggesting the refinement in commit history to make sure it becomes minimal and coherent. The same has been implemented.

@gnprice
Copy link
Member

gnprice commented Oct 20, 2025

Thanks. Some of these commits aren't coherent. For example this commit f314a74:

    deps: Update pigeon to `26.0.2` from `26.0.1`
    
    This commit is the result of the following commands:
        flutter pub upgrade --major-version pigeon
        tools/check --all-files --fix pigeon
    
    Changelog:
    
    https://pub.dev/packages/pigeon/changelog#2602
---
 .../kotlin/com/zulip/flutter/AndroidIntents.g.kt    | Bin 6118 -> 6118 bytes
 .../com/zulip/flutter/AndroidNotifications.g.kt     | Bin 30643 -> 30643 bytes
 ios/Runner/Notifications.g.swift                    |   2 +-
 3 files changed, 1 insertion(+), 1 deletion(-)

can't be right, because it says it involved flutter pub upgrade but there's no change to pubspec.lock.

One useful step for spotting this kind of issue is to run our tests at every commit. If they fail, the commit needs fixing.

It's straightforward to do that by hand. But a command which can be a useful shortcut for it is this:
git rebase --exec 'tools/check --diff @~'

@MritunjayTiwari14
Copy link
Contributor Author

Thank you @chrisbobbe for your patience, I have pushed a lot of new changes, PTAL!

Copy link

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

This PR adds a video call button to the compose box that allows users to insert video call links into their messages. The implementation supports multiple video chat providers (Jitsi, Zoom, and BigBlueButton) based on realm configuration.

Key changes:

  • Adds a new video icon button to the compose box attachment toolbar
  • Implements video call URL generation for Jitsi (default), Zoom (with OAuth), and BigBlueButton providers
  • Adds event handling for Zoom token authentication flow

Reviewed changes

Copilot reviewed 14 out of 34 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
lib/widgets/compose_box.dart Core implementation including ComposeCall class and _AddComposeCallUrlButton widget with provider-specific logic
lib/widgets/icons.dart Adds video icon constant
lib/model/store.dart Adds hasZoomToken state management and HasZoomTokenEvent handling
lib/model/realm.dart Adds video chat provider configuration fields
lib/api/route/video_call.dart New API routes for creating Zoom and BigBlueButton calls
lib/api/model/model.dart Adds RealmAvailableVideoChatProviders, VideoCallResponse, and RealmVideoChatProvider models
lib/api/model/events.dart Adds HasZoomTokenEvent for OAuth flow
lib/api/model/initial_snapshot.dart Adds video chat provider configuration fields to initial snapshot
lib/generated/l10n/*.dart Adds localized strings for video/voice call tooltips and error messages
assets/l10n/app_en.arb Source English localization strings
assets/icons/video.svg Video icon SVG asset
assets/icons/ZulipIcons.ttf Updated icon font with video icon
test/widgets/compose_box_test.dart Basic test for Jitsi video call functionality
test/example_data.dart Test fixtures for video chat provider configuration

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

try {
final connection = store.connection;
final result = await createBigBlueButtonCall(
connection, meetingName: "Null", //TODO: Fetch message stream title
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

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

The meeting name is hardcoded to "Null" which is likely not the intended value. The TODO comment indicates this should be the stream title, but implementing this is important for BigBlueButton calls to have meaningful meeting names.

Copilot uses AI. Check for mistakes.
"@errorCouldNotEditMessageTitle": {
"description": "Error title when an exception prevented us from opening the compose box for editing a message."
},
"errorCouldNotAppendCallUrl": "Fail to get call URL",
Copy link

Copilot AI Dec 12, 2025

Choose a reason for hiding this comment

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

The error message has incorrect grammar. It should read "Failed to get call URL" instead of "Fail to get call URL".

Suggested change
"errorCouldNotAppendCallUrl": "Fail to get call URL",
"errorCouldNotAppendCallUrl": "Failed to get call URL",

Copilot uses AI. Check for mistakes.
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! Here's a review of the API/model changes:

1c07e3f icons: Add 'video', from the Figma
585d056 api: Add realmVideoChatProvider to InitialSnapshot
ac3c1c0 api: Add realmAvailableVideoChatProviders to InitialSnapshot
2bd7232 api: Add hasZoomToken to InitialSnapshot
3e8e1de api: Add jitsi server url configurations to InitialSnapshot
340df70 realm: Add getters for realmAvailableVideoChatProviders
9c46324 realm: Add getters for jitsiServerUrl and realmVideoChatProvider
37a9d94 store: Add getter for hasZoomToken
0671977 api: Add routes to fetch zoom and bigBlueButton call url
f35502a api: Add event hasZoomToken

leaving the last commit for a later round of review:

3827b62 compose_box: Add Add video call button

/// For docs, search for "realm_video_chat_provider:"
/// in <https://zulip.com/api/register-queue>.
@JsonEnum(fieldRename: FieldRename.snake, valueField: "apiValue")
enum RealmVideoChatProvider {
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: It seems like this definition should go after both RealmEmojiItem and UserStatus. Can we define these "helper" definitions in the same order as their corresponding fields in InitialSnapshot?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Put RealmVideoChatProvider just after UserSettings since that was the only correlation that i was able to make from register-queue api docs since InitialSnapshot follow that api docs order.


final String realmName;

final int realmVideoChatProvider;
Copy link
Collaborator

Choose a reason for hiding this comment

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

api: Add realmVideoChatProvider to InitialSnapshot
Suggested change
final int realmVideoChatProvider;
final RealmVideoChatProvider realmVideoChatProvider;

(And rerun dart run build_runner build and edit test/example_data.dart)

Comment on lines 223 to 226
jitsi(apiValue: 1),
zoomUser(apiValue: 3),
bigBlueButton(apiValue: 4),
zoomServer(apiValue: 5),
Copy link
Collaborator

Choose a reason for hiding this comment

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

In some of these names, let's match the API documentation a bit more: jitsiMeet, zoomUserOAuth, zoomServerToServerOAuth.

Comment on lines 73 to 74
factory RealmAvailableVideoChatProviders.fromJson(Map<String, dynamic> json) =>
_$RealmAvailableVideoChatProvidersFromJson(json);
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: two-space indent


final int realmVideoChatProvider;

final String? realmJitsiServerUrl;
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit:

Suggested change
final String? realmJitsiServerUrl;
final String? realmJitsiServerUrl; // TODO(server-8)

Comment on lines 21 to 22
return connection.get('createBigBlueButtonCall', VideoCallResponse.fromJson,
'/calls/bigbluebutton/create', {'meeting_name': meetingName, 'voice_only': voiceOnly});
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
return connection.get('createBigBlueButtonCall', VideoCallResponse.fromJson,
'/calls/bigbluebutton/create', {'meeting_name': meetingName, 'voice_only': voiceOnly});
return connection.get(
'createBigBlueButtonCall', VideoCallResponse.fromJson, '/calls/bigbluebutton/create', {
'meeting_name': RawParameter(meetingName),
if (voiceOnly != null) 'voice_only': voiceOnly,
});

/// GET /api/v1/calls/bigbluebutton/create
Future<VideoCallResponse> createBigBlueButtonCall(ApiConnection connection, {
required String meetingName,
required bool voiceOnly,
Copy link
Collaborator

Choose a reason for hiding this comment

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

The API doc says this isn't required; let's make it optional:

Suggested change
required bool voiceOnly,
bool? voiceOnly

case 'presence': return PresenceEvent.fromJson(json);
case 'reaction': return ReactionEvent.fromJson(json);
case 'heartbeat': return HeartbeatEvent.fromJson(json);
case 'has_zoom_token': return HasZoomTokenEvent.fromJson(json);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's put this just after case 'user_settings':, I think; similarly to the ordering choices in RealmStore. (And reorder the HasZoomTokenEvent class definition correspondingly.)

Comment on lines 769 to 770
case HasZoomTokenEvent():
assert(debugLog("server event: has_zoom_token"));
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's put this just after the case UserSettingsUpdateEvent():.


/// A Zulip event of type `hasZoomToken`: https://zulip.com/api/get-events#has_zoom_token
@JsonSerializable(fieldRename: FieldRename.snake)
class HasZoomTokenEvent extends Event {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Commit-message nit:

api: Add event `hasZoomToken`

The event is named HasZoomTokenEvent in our code; hasZoomToken isn't a name we use for the event.

@MritunjayTiwari14
Copy link
Contributor Author

MritunjayTiwari14 commented Dec 21, 2025

Thank you @chrisbobbe for the Review, have pushed some new changes as well as a reply to your comment in review #1824(comment). PTAL.

Regarding the test case I have open a discussion on CZO: #mobile-dev-help > compose call button test @ 💬

Edit: Some Changes were not pushed, i will push them as soon as possible.

@MritunjayTiwari14
Copy link
Contributor Author

I've also added test for Zoom video call insertion in the final commit. PTAL! @chrisbobbe

@chrisbobbe
Copy link
Collaborator

chrisbobbe commented Jan 2, 2026

We do want to support all the expected platforms—Jitsi Meet, Big Blue Button, and the two Zoom configurations. It looks like the last commit is meant to add support for all of them all at once, though, and it feels kind of overwhelming to review all of them together. Would you make separate commits for supporting each platform, please, starting with the simplest, which I think is Jitsi? If I could see each change on its own, it would make my reviews more efficient and help us be more confident in the result.

@MritunjayTiwari14
Copy link
Contributor Author

MritunjayTiwari14 commented Jan 6, 2026

Thank you @chrisbobbe for the patience and advice. I have expanded the final commit into several parts for each meeting application configuration. PTAL!

Edit: Fixing the failing CI 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.

Add "start video call" button in compose

3 participants