Skip to content

[MM-69735] Improve DM call user experience - #10017

Open
M-ZubairAhmed wants to merge 25 commits into
mainfrom
dm-calls
Open

[MM-69735] Improve DM call user experience#10017
M-ZubairAhmed wants to merge 25 commits into
mainfrom
dm-calls

Conversation

@M-ZubairAhmed

@M-ZubairAhmed M-ZubairAhmed commented Aug 6, 2026

Copy link
Copy Markdown
Member

Summary

Ticket Link

Checklist

  • Added or updated unit tests (required for all new features)
  • Has UI changes
  • Includes text changes and localization file updates
  • Have tested against the 5 core themes to ensure consistency between them.
  • Have run E2E tests by adding label E2E/Run (or E2E/Run-iOS / E2E/Run-Android for platform-specific runs).

Device Information

This PR was tested on:

Screenshots

Release Note

Improved DM call experience to phone like calls behavior.

@M-ZubairAhmed

Copy link
Copy Markdown
Member Author

/update-branch

@mattermost-build

Copy link
Copy Markdown
Contributor

Error trying to update the PR.
Please do it manually.

@M-ZubairAhmed

Copy link
Copy Markdown
Member Author

/update-branch

@mattermost-build

Copy link
Copy Markdown
Contributor

Error trying to update the PR.
Please do it manually.

@mattermost-build mattermost-build added the E2E/Run Triggers E2E tests on both iOS and Android via Matterwick label Aug 7, 2026
@mattermost-build mattermost-build added E2E/Run Triggers E2E tests on both iOS and Android via Matterwick and removed E2E/Run Triggers E2E tests on both iOS and Android via Matterwick labels Aug 7, 2026
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

Coverage Comparison Report

Generated on August 24, 2026 at 12:02:14 UTC

+-----------------+------------+------------+-----------+
| Metric          | Main       | This PR    | Diff      |
+-----------------+------------+------------+-----------+
| Lines           |     88.39% |     88.42% |     0.03% |
| Statements      |     88.25% |     88.28% |     0.03% |
| Branches        |     77.33% |     77.46% |     0.13% |
| Functions       |     87.73% |     87.79% |     0.06% |
+-----------------+------------+------------+-----------+
| Total           |     85.42% |     85.48% |     0.06% |
+-----------------+------------+------------+-----------+

@mattermost-build mattermost-build removed the E2E/Run Triggers E2E tests on both iOS and Android via Matterwick label Aug 7, 2026
@M-ZubairAhmed

Copy link
Copy Markdown
Member Author

/update-branch

@mattermost-build

Copy link
Copy Markdown
Contributor

Error trying to update the PR.
Please do it manually.

@mattermost-build mattermost-build added E2E/Run Triggers E2E tests on both iOS and Android via Matterwick and removed E2E/Run Triggers E2E tests on both iOS and Android via Matterwick labels Aug 12, 2026
@amyblais amyblais added this to the v2.44.0 milestone Aug 13, 2026
@mattermost-build mattermost-build added the E2E/Run Triggers E2E tests on both iOS and Android via Matterwick label Aug 17, 2026
@M-ZubairAhmed M-ZubairAhmed removed the E2E/Run Triggers E2E tests on both iOS and Android via Matterwick label Aug 17, 2026
@mattermost-build mattermost-build added the E2E/Run Triggers E2E tests on both iOS and Android via Matterwick label Aug 17, 2026
@M-ZubairAhmed

Copy link
Copy Markdown
Member Author

/update-branch

@mattermost-build

Copy link
Copy Markdown
Contributor

Error trying to update the PR.
Please do it manually.

@mattermost-build mattermost-build removed the E2E/Run Triggers E2E tests on both iOS and Android via Matterwick label Aug 17, 2026
@amyblais amyblais removed this from the v2.44.0 milestone Aug 17, 2026
@mattermost-build mattermost-build removed the E2E/Run Triggers E2E tests on both iOS and Android via Matterwick label Aug 18, 2026
@enahum

enahum commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

And the callee doesn't get prompted to allow their mic in this state from the lock screen CallKit UI.

Callkit does not allow to request a permission in the lock screen, we should probably request the permission when the user uses the app and we detect that the server has calls installed proactively and not on first use

@matthewbirtch

@matthewbirtch

Copy link
Copy Markdown
Contributor

Callkit does not allow to request a permission in the lock screen, we should probably request the permission when the user uses the app and we detect that the server has calls installed proactively and not on first use

Thanks @enahum. I wondered about that. It think what you'e proposed makes sense.

@M-ZubairAhmed

Copy link
Copy Markdown
Member Author

@matthewbirtch

can you clarify this

Once connected to a DM call, I still see 'No one is talking'. That should be supressed. We should just show the avatar of the person you're on a call with and their name (without 'is talking').

@mattermost-build mattermost-build added the E2E/Run Triggers E2E tests on both iOS and Android via Matterwick label Aug 19, 2026
@matthewbirtch

Copy link
Copy Markdown
Contributor

can you clarify this

Once connected to a DM call, I still see 'No one is talking'. That should be supressed. We should just show the avatar of the person you're on a call with and their name (without 'is talking').

Sure @M-ZubairAhmed. For the DM context, I was thinking that we could/should remove the 'No one is talking' state altogether. So when no one is actively speaking, we just show the avatar and name of the user you're on the call with. Like this:

image

If this is non-trivial, let me know. We could descope this for now if that's the case. Now that I think of it, we did not implement this in the webapp changes, so maybe it makes sense to defer this for now.

@M-ZubairAhmed
M-ZubairAhmed requested review from enahum and removed request for carlisgg August 20, 2026 06:09

@enahum enahum left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One more question: is it expected that joining a call takes me to the channel screen?

import React, {forwardRef} from 'react';
import Animated, {useAnimatedStyle, useDerivedValue, type SharedValue} from 'react-native-reanimated';

import {type NavigationButtonProps} from '@components/navigation_button';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: I see no reason for this change

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

reverted

import {View} from 'react-native';

import CompassIcon from '@components/compass_icon';
import {type NavigationButtonProps} from '@components/navigation_button';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same here, no reason

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

reverted

Comment on lines +20 to +21
speakingUserStyle: StyleProp<TextStyle>;
speakingPostfixStyle: StyleProp<TextStyle>;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why are we passing the styles as props and not defining them in the component?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

changed

Comment thread app/products/calls/observers/index.ts Outdated
distinctUntilChanged(),
);

// TODO: Remove startTime fallback

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Anything to do here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

removed

Comment thread app/products/calls/state/actions.ts Outdated
setIncomingCalls({...getIncomingCalls(), currentRingingCallId: undefined});
// The incoming ring and the outbound ringback share the one native player, so stop
// whichever is playing through its own owner
stopRingback();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

So I place a call, send the app to the background, no ring back on my call?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this was defensive to prevent using the player which might be needed for ringtone. But, now that ringtones on iOS are always handled by CallKit, we can skip stopRingback on iOS and allow ringback tone in background.

@matthewbirtch matthewbirtch Aug 24, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If the app is still attempting to connect while backgrounded, then we should keep the outbound sound ringing.

Comment thread app/products/calls/state/actions.ts Outdated

const enabled = user.notifyProps?.calls_mobile_sound ? user.notifyProps.calls_mobile_sound === 'true' : user.notifyProps?.calls_desktop_sound === 'true';
if (!enabled) {
// No user shouldn't happen, so don't bother localizing and displaying an alert.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't understand this comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

clarified

Comment thread app/products/calls/state/actions.ts Outdated
const {database} = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
const channel = await getChannelById(database, channelId);
if (!getDMCalleeId(currentCall.myUserId, channel)) {
logDebug('startRingbackIfNeeded skipped: not a 1:1 DM with someone else');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

So for every non DM we get this log? Needed?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

removed

Comment thread app/products/calls/state/actions.ts Outdated
nextCurrentCall.mySessionId = sessionId;
}

// TODO: Since this is a synchronous event path, we should only set dmCalleeAnsweredAt for DM calls.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Anything to do here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

revoved

/// registration failed and `didDeactivate` will never fire, this is the only
/// teardown path.
@objc public func resetSession() {
rtcSession.lockForConfiguration()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why this change?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

RTCAudioSession requires the configuration lock for its mutating calls

Added identifiers to test cases for the DM call button to improve traceability. The tests now include specific references to the associated ticket (MM-70370) for better tracking of changes related to the call button's visibility in different channel types.
Updated the CallStatusText component to utilize theme-based styles for speaking user and postfix text, improving consistency and maintainability. Removed unnecessary style props and integrated the styles directly within the component. Additionally, cleaned up imports in the current call bar and header components for better organization.
Removed outdated TODO comments regarding startTime fallback and DM call handling. Updated comments for clarity on user presence checks and the handling of dmCalleeAnsweredAt, ensuring consistency across call types. This enhances code readability and maintains focus on the intended functionality.
@mattermost-build mattermost-build added E2E/Run Triggers E2E tests on both iOS and Android via Matterwick and removed E2E/Run Triggers E2E tests on both iOS and Android via Matterwick labels Aug 24, 2026
@M-ZubairAhmed
M-ZubairAhmed requested a review from enahum August 24, 2026 11:40
@M-ZubairAhmed

Copy link
Copy Markdown
Member Author

/update-branch

@mattermost-build mattermost-build added E2E/Run Triggers E2E tests on both iOS and Android via Matterwick and removed E2E/Run Triggers E2E tests on both iOS and Android via Matterwick labels Aug 24, 2026
@M-ZubairAhmed

Copy link
Copy Markdown
Member Author

One more question: is it expected that joining a call takes me to the channel screen?

Yes thats for DM calls only

@enahum

enahum commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

One more question: is it expected that joining a call takes me to the channel screen?

Yes thats for DM calls only

If that is the case, two follow up questions:

Does this work when answering the call through Callkit, with and without the phone locked

, is it also expected to be taken to the call screen for DM's when I return to the app when it was sitting in the background with an active call?

@mattermost-build mattermost-build removed the E2E/Run Triggers E2E tests on both iOS and Android via Matterwick label Aug 24, 2026
On iOS, CallKit owns the inbound ringtone and never uses the native
audio player, so there is no shared-player conflict that would justify
stopping ringback when the app backgrounds. Only stop ringback on
background on Android, where inbound ring and ringback do share the
one native MediaPlayer.
@mattermost-build mattermost-build added E2E/Run Triggers E2E tests on both iOS and Android via Matterwick and removed E2E/Run Triggers E2E tests on both iOS and Android via Matterwick labels Aug 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

2: Dev Review Requires review by a core commiter 2: UX Review Requires review by a UX Designer 3: QA Review Requires review by a QA tester Build Apps for PR Build the mobile app for iOS and Android to test Docs/Needed Requires documentation release-note

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants