Update call UI to new designs.

This commit is contained in:
Cody Henthorne
2021-08-09 11:56:06 -04:00
parent 94b9a458e7
commit 655e43a079
16 changed files with 441 additions and 201 deletions

View File

@@ -17,8 +17,6 @@
package org.thoughtcrime.securesms;
import static org.thoughtcrime.securesms.components.sensors.Orientation.PORTRAIT_BOTTOM_EDGE;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.PictureInPictureParams;
@@ -82,6 +80,8 @@ import org.whispersystems.signalservice.api.messages.calls.HangupMessage;
import java.util.List;
import java.util.Optional;
import static org.thoughtcrime.securesms.components.sensors.Orientation.PORTRAIT_BOTTOM_EDGE;
public class WebRtcCallActivity extends BaseActivity implements SafetyNumberChangeDialog.Callback {
private static final String TAG = Log.tag(WebRtcCallActivity.class);
@@ -772,7 +772,7 @@ public class WebRtcCallActivity extends BaseActivity implements SafetyNumberChan
setRequestedOrientation(feature.isPresent() ? ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
if (feature.isPresent()) {
FoldingFeature foldingFeature = (FoldingFeature) feature.get();
Rect bounds = foldingFeature.getBounds();
Rect bounds = foldingFeature.getBounds();
if (foldingFeature.getState() == FoldingFeature.State.HALF_OPENED && bounds.top == bounds.bottom) {
Log.d(TAG, "OnWindowLayoutInfo accepted: ensure call view is in table-top display mode");
viewModel.setFoldableState(WebRtcControls.FoldableState.folded(bounds.top));

View File

@@ -196,6 +196,14 @@ public class CallParticipantView extends ConstraintLayout {
pipAvatar.setVisibility(shouldRenderInPip ? View.VISIBLE : View.GONE);
}
void hideAvatar() {
avatar.setAlpha(0f);
}
void showAvatar() {
avatar.setAlpha(1f);
}
void useLargeAvatar() {
changeAvatarParams(LARGE_AVATAR);
}

View File

@@ -34,6 +34,7 @@ public class CallParticipantsLayout extends FlexboxLayout {
private CallParticipant focusedParticipant = null;
private boolean shouldRenderInPip;
private boolean isPortrait;
private boolean isIncomingRing;
private LayoutStrategy layoutStrategy;
public CallParticipantsLayout(@NonNull Context context) {
@@ -52,13 +53,16 @@ public class CallParticipantsLayout extends FlexboxLayout {
@NonNull CallParticipant focusedParticipant,
boolean shouldRenderInPip,
boolean isPortrait,
boolean isIncomingRing,
@NonNull LayoutStrategy layoutStrategy)
{
this.callParticipants = callParticipants;
this.focusedParticipant = focusedParticipant;
this.shouldRenderInPip = shouldRenderInPip;
this.isPortrait = isPortrait;
this.isIncomingRing = isIncomingRing;
this.layoutStrategy = layoutStrategy;
setFlexDirection(layoutStrategy.getFlexDirection());
updateLayout();
}
@@ -125,6 +129,12 @@ public class CallParticipantsLayout extends FlexboxLayout {
cardView.setRadius(0);
}
if (isIncomingRing) {
callParticipantView.hideAvatar();
} else {
callParticipantView.showAvatar();
}
if (count > 2) {
callParticipantView.useSmallAvatar();
} else {

View File

@@ -197,6 +197,10 @@ public final class CallParticipantsState {
.or(() -> includeSelf ? OptionalLong.of(1L) : OptionalLong.empty());
}
public boolean isIncomingRing() {
return callState == WebRtcViewModel.State.CALL_INCOMING;
}
public static @NonNull CallParticipantsState update(@NonNull CallParticipantsState oldState,
@NonNull WebRtcViewModel webRtcViewModel,
boolean enableVideo)

View File

@@ -16,14 +16,16 @@ class WebRtcCallParticipantsPage {
private final boolean isRenderInPip;
private final boolean isPortrait;
private final boolean isLandscapeEnabled;
private final boolean isIncomingRing;
static WebRtcCallParticipantsPage forMultipleParticipants(@NonNull List<CallParticipant> callParticipants,
@NonNull CallParticipant focusedParticipant,
boolean isRenderInPip,
boolean isPortrait,
boolean isLandscapeEnabled)
boolean isLandscapeEnabled,
boolean isIncomingRing)
{
return new WebRtcCallParticipantsPage(callParticipants, focusedParticipant, false, isRenderInPip, isPortrait, isLandscapeEnabled);
return new WebRtcCallParticipantsPage(callParticipants, focusedParticipant, false, isRenderInPip, isPortrait, isLandscapeEnabled, isIncomingRing);
}
static WebRtcCallParticipantsPage forSingleParticipant(@NonNull CallParticipant singleParticipant,
@@ -31,7 +33,7 @@ class WebRtcCallParticipantsPage {
boolean isPortrait,
boolean isLandscapeEnabled)
{
return new WebRtcCallParticipantsPage(Collections.singletonList(singleParticipant), singleParticipant, true, isRenderInPip, isPortrait, isLandscapeEnabled);
return new WebRtcCallParticipantsPage(Collections.singletonList(singleParticipant), singleParticipant, true, isRenderInPip, isPortrait, isLandscapeEnabled, false);
}
private WebRtcCallParticipantsPage(@NonNull List<CallParticipant> callParticipants,
@@ -39,7 +41,8 @@ class WebRtcCallParticipantsPage {
boolean isSpeaker,
boolean isRenderInPip,
boolean isPortrait,
boolean isLandscapeEnabled)
boolean isLandscapeEnabled,
boolean isIncomingRing)
{
this.callParticipants = callParticipants;
this.focusedParticipant = focusedParticipant;
@@ -47,6 +50,7 @@ class WebRtcCallParticipantsPage {
this.isRenderInPip = isRenderInPip;
this.isPortrait = isPortrait;
this.isLandscapeEnabled = isLandscapeEnabled;
this.isIncomingRing = isIncomingRing;
}
public @NonNull List<CallParticipant> getCallParticipants() {
@@ -69,6 +73,10 @@ class WebRtcCallParticipantsPage {
return isPortrait;
}
public boolean isIncomingRing() {
return isIncomingRing;
}
public @NonNull CallParticipantsLayout.LayoutStrategy getLayoutStrategy() {
return CallParticipantsLayoutStrategies.getStrategy(isPortrait, isLandscapeEnabled);
}

View File

@@ -86,7 +86,7 @@ class WebRtcCallParticipantsPagerAdapter extends ListAdapter<WebRtcCallParticipa
@Override
void bind(WebRtcCallParticipantsPage page) {
callParticipantsLayout.update(page.getCallParticipants(), page.getFocusedParticipant(), page.isRenderInPip(), page.isPortrait(), page.getLayoutStrategy());
callParticipantsLayout.update(page.getCallParticipants(), page.getFocusedParticipant(), page.isRenderInPip(), page.isPortrait(), page.isIncomingRing(), page.getLayoutStrategy());
}
}

View File

@@ -6,7 +6,6 @@ import android.graphics.ColorMatrixColorFilter;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
@@ -17,7 +16,6 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.appcompat.widget.Toolbar;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
import androidx.constraintlayout.widget.Guideline;
@@ -38,6 +36,7 @@ import com.google.common.collect.Sets;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.animation.ResizeAnimation;
import org.thoughtcrime.securesms.components.AccessibleToggleButton;
import org.thoughtcrime.securesms.components.AvatarImageView;
import org.thoughtcrime.securesms.contacts.avatars.ProfileContactPhoto;
import org.thoughtcrime.securesms.events.CallParticipant;
import org.thoughtcrime.securesms.events.WebRtcViewModel;
@@ -48,6 +47,7 @@ import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.ringrtc.CameraState;
import org.thoughtcrime.securesms.util.BlurTransformation;
import org.thoughtcrime.securesms.util.SetUtil;
import org.thoughtcrime.securesms.util.ThrottledDebouncer;
import org.thoughtcrime.securesms.util.ViewUtil;
import org.thoughtcrime.securesms.util.views.Stub;
import org.thoughtcrime.securesms.webrtc.CallParticipantsViewState;
@@ -70,8 +70,11 @@ public class WebRtcCallView extends ConstraintLayout {
public static final int CONTROLS_HEIGHT = 98;
private WebRtcAudioOutputToggleButton audioToggle;
private TextView audioToggleLabel;
private AccessibleToggleButton videoToggle;
private TextView videoToggleLabel;
private AccessibleToggleButton micToggle;
private TextView micToggleLabel;
private ViewGroup smallLocalRenderFrame;
private CallParticipantView smallLocalRender;
private View largeLocalRenderFrame;
@@ -80,32 +83,40 @@ public class WebRtcCallView extends ConstraintLayout {
private ImageView largeLocalRenderNoVideoAvatar;
private TextView recipientName;
private TextView status;
private TextView incomingRingStatus;
private ConstraintLayout parent;
private ConstraintLayout participantsParent;
private ControlsListener controlsListener;
private RecipientId recipientId;
private ImageView answer;
private ImageView cameraDirectionToggle;
private TextView cameraDirectionToggleLabel;
private PictureInPictureGestureHelper pictureInPictureGestureHelper;
private ImageView hangup;
private TextView hangupLabel;
private View answerWithAudio;
private View answerWithAudioLabel;
private View topGradient;
private View footerGradient;
private View startCallControls;
private ViewPager2 callParticipantsPager;
private RecyclerView callParticipantsRecycler;
private Toolbar toolbar;
private ConstraintLayout toolbar;
private MaterialButton startCall;
private TextView participantCount;
private Stub<FrameLayout> groupCallSpeakerHint;
private Stub<View> groupCallFullStub;
private View errorButton;
private int pagerBottomMarginDp;
private boolean controlsVisible = true;
private Guideline showParticipantsGuideline;
private Guideline topFoldGuideline;
private Guideline callScreenTopFoldGuideline;
private View foldParticipantCountWrapper;
private TextView foldParticipantCount;
private AvatarImageView largeHeaderAvatar;
private ConstraintSet smallHeaderConstraints;
private Guideline statusBarGuideline;
private View fullScreenShade;
private WebRtcCallParticipantsPagerAdapter pagerAdapter;
private WebRtcCallParticipantsRecyclerAdapter recyclerAdapter;
@@ -114,11 +125,14 @@ public class WebRtcCallView extends ConstraintLayout {
private final Set<View> incomingCallViews = new HashSet<>();
private final Set<View> topViews = new HashSet<>();
private final Set<View> visibleViewSet = new HashSet<>();
private final Set<View> allTimeVisibleViews = new HashSet<>();
private final Set<View> adjustableMarginsSet = new HashSet<>();
private final Set<View> rotatableControls = new HashSet<>();
private WebRtcControls controls = WebRtcControls.NONE;
private final Runnable fadeOutRunnable = () -> {
private final ThrottledDebouncer throttledDebouncer = new ThrottledDebouncer(TRANSITION_DURATION_MILLIS);
private WebRtcControls controls = WebRtcControls.NONE;
private final Runnable fadeOutRunnable = () -> {
if (isAttachedToWindow() && controls.isFadeOutEnabled()) fadeOutControls();
};
@@ -138,8 +152,11 @@ public class WebRtcCallView extends ConstraintLayout {
super.onFinishInflate();
audioToggle = findViewById(R.id.call_screen_speaker_toggle);
audioToggleLabel = findViewById(R.id.call_screen_speaker_toggle_label);
videoToggle = findViewById(R.id.call_screen_video_toggle);
videoToggleLabel = findViewById(R.id.call_screen_video_toggle_label);
micToggle = findViewById(R.id.call_screen_audio_mic_toggle);
micToggleLabel = findViewById(R.id.call_screen_audio_mic_toggle_label);
smallLocalRenderFrame = findViewById(R.id.call_screen_pip);
smallLocalRender = findViewById(R.id.call_screen_small_local_renderer);
largeLocalRenderFrame = findViewById(R.id.call_screen_large_local_renderer_frame);
@@ -148,32 +165,38 @@ public class WebRtcCallView extends ConstraintLayout {
largeLocalRenderNoVideoAvatar = findViewById(R.id.call_screen_large_local_video_off_avatar);
recipientName = findViewById(R.id.call_screen_recipient_name);
status = findViewById(R.id.call_screen_status);
incomingRingStatus = findViewById(R.id.call_screen_incoming_ring_status);
parent = findViewById(R.id.call_screen);
participantsParent = findViewById(R.id.call_screen_participants_parent);
answer = findViewById(R.id.call_screen_answer_call);
cameraDirectionToggle = findViewById(R.id.call_screen_camera_direction_toggle);
cameraDirectionToggleLabel = findViewById(R.id.call_screen_camera_direction_toggle_label);
hangup = findViewById(R.id.call_screen_end_call);
hangupLabel = findViewById(R.id.call_screen_end_call_label);
answerWithAudio = findViewById(R.id.call_screen_answer_with_audio);
answerWithAudioLabel = findViewById(R.id.call_screen_answer_with_audio_label);
topGradient = findViewById(R.id.call_screen_header_gradient);
footerGradient = findViewById(R.id.call_screen_footer_gradient);
startCallControls = findViewById(R.id.call_screen_start_call_controls);
callParticipantsPager = findViewById(R.id.call_screen_participants_pager);
callParticipantsRecycler = findViewById(R.id.call_screen_participants_recycler);
toolbar = findViewById(R.id.call_screen_toolbar);
toolbar = findViewById(R.id.call_screen_header);
startCall = findViewById(R.id.call_screen_start_call_start_call);
errorButton = findViewById(R.id.call_screen_error_cancel);
groupCallSpeakerHint = new Stub<>(findViewById(R.id.call_screen_group_call_speaker_hint));
groupCallFullStub = new Stub<>(findViewById(R.id.group_call_call_full_view));
showParticipantsGuideline = findViewById(R.id.call_screen_show_participants_guideline);
topFoldGuideline = findViewById(R.id.fold_top_guideline);
callScreenTopFoldGuideline = findViewById(R.id.fold_top_call_screen_guideline);
foldParticipantCountWrapper = findViewById(R.id.fold_show_participants_menu_counter_wrapper);
foldParticipantCount = findViewById(R.id.fold_show_participants_menu_counter);
largeHeaderAvatar = findViewById(R.id.call_screen_header_avatar);
statusBarGuideline = findViewById(R.id.call_screen_status_bar_guideline);
fullScreenShade = findViewById(R.id.call_screen_full_shade);
View topGradient = findViewById(R.id.call_screen_header_gradient);
View decline = findViewById(R.id.call_screen_decline_call);
View answerLabel = findViewById(R.id.call_screen_answer_call_label);
View declineLabel = findViewById(R.id.call_screen_decline_call_label);
View cancelStartCall = findViewById(R.id.call_screen_start_call_cancel);
callParticipantsPager.setPageTransformer(new MarginPageTransformer(ViewUtil.dpToPx(4)));
@@ -239,7 +262,6 @@ public class WebRtcCallView extends ConstraintLayout {
controlsListener.onStartCall(videoToggle.isChecked());
}
});
cancelStartCall.setOnClickListener(v -> runIfNonNull(controlsListener, ControlsListener::onCancelStartCall));
ColorMatrix greyScaleMatrix = new ColorMatrix();
greyScaleMatrix.setSaturation(0);
@@ -261,6 +283,9 @@ public class WebRtcCallView extends ConstraintLayout {
rotatableControls.add(cameraDirectionToggle);
rotatableControls.add(decline);
rotatableControls.add(smallLocalRender.findViewById(R.id.call_participant_mic_muted));
smallHeaderConstraints = new ConstraintSet();
smallHeaderConstraints.clone(getContext(), R.layout.webrtc_call_view_header_small);
}
@Override
@@ -274,7 +299,6 @@ public class WebRtcCallView extends ConstraintLayout {
@Override
protected boolean fitSystemWindows(Rect insets) {
Guideline statusBarGuideline = findViewById(R.id.call_screen_status_bar_guideline);
Guideline navigationBarGuideline = findViewById(R.id.call_screen_navigation_bar_guideline);
statusBarGuideline.setGuidelineBegin(insets.top);
@@ -327,27 +351,22 @@ public class WebRtcCallView extends ConstraintLayout {
List<WebRtcCallParticipantsPage> pages = new ArrayList<>(2);
if (!state.getGridParticipants().isEmpty()) {
pages.add(WebRtcCallParticipantsPage.forMultipleParticipants(state.getGridParticipants(), state.getFocusedParticipant(), state.isInPipMode(), isPortrait, isLandscapeEnabled));
pages.add(WebRtcCallParticipantsPage.forMultipleParticipants(state.getGridParticipants(), state.getFocusedParticipant(), state.isInPipMode(), isPortrait, isLandscapeEnabled, state.isIncomingRing()));
}
if (state.getFocusedParticipant() != CallParticipant.EMPTY && state.getAllRemoteParticipants().size() > 1) {
pages.add(WebRtcCallParticipantsPage.forSingleParticipant(state.getFocusedParticipant(), state.isInPipMode(), isPortrait, isLandscapeEnabled));
}
if ((state.getGroupCallState().isNotIdle() && state.getRemoteDevicesCount().orElse(0) > 0) || state.getGroupCallState().isConnected()) {
recipientName.setText(state.getRemoteParticipantsDescription(getContext()));
} else if (state.getGroupCallState().isNotIdle()) {
recipientName.setText(getContext().getString(R.string.WebRtcCallView__s_group_call, Recipient.resolved(recipientId).getDisplayName(getContext())));
if (state.getCallState() == WebRtcViewModel.State.CALL_PRE_JOIN && state.getGroupCallState().isNotIdle()) {
status.setText(state.getRemoteParticipantsDescription(getContext()));
}
if (state.getGroupCallState().isNotIdle() && participantCount != null) {
if (state.getGroupCallState().isNotIdle()) {
String text = state.getParticipantCount()
.mapToObj(String::valueOf).orElse("\u2014");
boolean enabled = state.getParticipantCount().isPresent();
participantCount.setText(text);
participantCount.setEnabled(enabled);
foldParticipantCount.setText(text);
foldParticipantCount.setEnabled(enabled);
}
@@ -450,20 +469,13 @@ public class WebRtcCallView extends ConstraintLayout {
recipientId = recipient.getId();
largeHeaderAvatar.setRecipient(recipient, false);
if (recipient.isGroup()) {
if (toolbar.getMenu().findItem(R.id.menu_group_call_participants_list) == null) {
toolbar.inflateMenu(R.menu.group_call);
View showParticipants = toolbar.getMenu().findItem(R.id.menu_group_call_participants_list).getActionView();
showParticipants.setAlpha(0);
showParticipants.setOnClickListener(unused -> showParticipantsList());
foldParticipantCountWrapper.setOnClickListener(unused -> showParticipantsList());
participantCount = showParticipants.findViewById(R.id.show_participants_menu_counter);
}
} else {
recipientName.setText(recipient.getDisplayName(getContext()));
foldParticipantCountWrapper.setOnClickListener(unused -> showParticipantsList());
}
recipientName.setText(recipient.getDisplayName(getContext()));
}
public void setStatus(@NonNull String status) {
@@ -515,18 +527,21 @@ public class WebRtcCallView extends ConstraintLayout {
visibleViewSet.clear();
if (webRtcControls.adjustForFold()) {
showParticipantsGuideline.setGuidelineBegin(-1);
showParticipantsGuideline.setGuidelineEnd(webRtcControls.getFold());
topFoldGuideline.setGuidelineEnd(webRtcControls.getFold());
callScreenTopFoldGuideline.setGuidelineEnd(webRtcControls.getFold());
if (webRtcControls.displayGroupMembersButton()) {
visibleViewSet.add(foldParticipantCountWrapper);
}
} else {
showParticipantsGuideline.setGuidelineBegin(((LayoutParams) statusBarGuideline.getLayoutParams()).guideBegin);
showParticipantsGuideline.setGuidelineEnd(-1);
topFoldGuideline.setGuidelineEnd(0);
callScreenTopFoldGuideline.setGuidelineEnd(0);
}
setShowParticipantsState(webRtcControls.adjustForFold());
if (webRtcControls.displayGroupMembersButton()) {
visibleViewSet.add(foldParticipantCountWrapper);
foldParticipantCount.setClickable(webRtcControls.adjustForFold());
}
if (webRtcControls.displayStartCallControls()) {
visibleViewSet.add(footerGradient);
@@ -548,12 +563,6 @@ public class WebRtcCallView extends ConstraintLayout {
groupCallFullStub.get().setVisibility(View.GONE);
}
MenuItem item = toolbar.getMenu().findItem(R.id.menu_group_call_participants_list);
if (item != null) {
item.setVisible(webRtcControls.displayGroupMembersButton());
item.setEnabled(webRtcControls.displayGroupMembersButton());
}
if (webRtcControls.displayTopViews()) {
visibleViewSet.addAll(topViews);
}
@@ -561,7 +570,9 @@ public class WebRtcCallView extends ConstraintLayout {
if (webRtcControls.displayIncomingCallButtons()) {
visibleViewSet.addAll(incomingCallViews);
status.setText(R.string.WebRtcCallView__signal_voice_call);
incomingRingStatus.setVisibility(VISIBLE);
incomingRingStatus.setText(R.string.WebRtcCallView__signal_call);
answer.setImageDrawable(AppCompatResources.getDrawable(getContext(), R.drawable.webrtc_call_screen_answer));
}
@@ -569,12 +580,19 @@ public class WebRtcCallView extends ConstraintLayout {
visibleViewSet.add(answerWithAudio);
visibleViewSet.add(answerWithAudioLabel);
status.setText(R.string.WebRtcCallView__signal_video_call);
incomingRingStatus.setVisibility(VISIBLE);
incomingRingStatus.setText(R.string.WebRtcCallView__signal_video_call);
answer.setImageDrawable(AppCompatResources.getDrawable(getContext(), R.drawable.webrtc_call_screen_answer_with_video));
}
if (!webRtcControls.displayIncomingCallButtons() && !webRtcControls.displayAnswerWithAudio()){
incomingRingStatus.setVisibility(GONE);
}
if (webRtcControls.displayAudioToggle()) {
visibleViewSet.add(audioToggle);
visibleViewSet.add(audioToggleLabel);
audioToggle.setControlAvailability(webRtcControls.enableHandsetInAudioToggle(),
webRtcControls.enableHeadsetInAudioToggle());
@@ -584,19 +602,23 @@ public class WebRtcCallView extends ConstraintLayout {
if (webRtcControls.displayCameraToggle()) {
visibleViewSet.add(cameraDirectionToggle);
visibleViewSet.add(cameraDirectionToggleLabel);
}
if (webRtcControls.displayEndCall()) {
visibleViewSet.add(hangup);
visibleViewSet.add(hangupLabel);
visibleViewSet.add(footerGradient);
}
if (webRtcControls.displayMuteAudio()) {
visibleViewSet.add(micToggle);
visibleViewSet.add(micToggleLabel);
}
if (webRtcControls.displayVideoToggle()) {
visibleViewSet.add(videoToggle);
visibleViewSet.add(videoToggleLabel);
}
if (webRtcControls.displaySmallOngoingCallButtons()) {
@@ -611,6 +633,14 @@ public class WebRtcCallView extends ConstraintLayout {
callParticipantsRecycler.setVisibility(View.GONE);
}
if (webRtcControls.showFullScreenShade()) {
fullScreenShade.setVisibility(VISIBLE);
visibleViewSet.remove(topGradient);
visibleViewSet.remove(footerGradient);
} else {
fullScreenShade.setVisibility(GONE);
}
if (webRtcControls.isFadeOutEnabled()) {
if (!controls.isFadeOutEnabled()) {
scheduleFadeOut();
@@ -627,20 +657,26 @@ public class WebRtcCallView extends ConstraintLayout {
scheduleFadeOut();
}
boolean forceUpdate = webRtcControls.adjustForFold() && !controls.adjustForFold();
controls = webRtcControls;
if (!controls.isFadeOutEnabled()) {
controlsVisible = true;
}
allTimeVisibleViews.addAll(visibleViewSet);
if (!visibleViewSet.equals(lastVisibleSet) ||
!controls.isFadeOutEnabled()) {
!controls.isFadeOutEnabled() ||
(webRtcControls.showSmallHeader() && largeHeaderAvatar.getVisibility() == View.VISIBLE) ||
forceUpdate)
{
if (controlsListener != null) {
controlsListener.showSystemUI();
}
fadeInNewUiState(lastVisibleSet, webRtcControls.displaySmallOngoingCallButtons());
throttledDebouncer.publish(() -> fadeInNewUiState(webRtcControls.displaySmallOngoingCallButtons(), webRtcControls.showSmallHeader()));
}
onWindowSystemUiVisibilityChanged(getWindowSystemUiVisibility());
@@ -660,18 +696,6 @@ public class WebRtcCallView extends ConstraintLayout {
}
}
private void setShowParticipantsState(boolean isFolded) {
MenuItem item = toolbar.getMenu().findItem(R.id.menu_group_call_participants_list);
if (item != null) {
View showParticipants = item.getActionView();
showParticipants.animate().alpha(isFolded ? 0f : 1f);
showParticipants.setClickable(!isFolded);
foldParticipantCountWrapper.animate().alpha(isFolded ? 1f : 0f);
foldParticipantCount.setClickable(isFolded);
}
}
private void expandPip(@NonNull CallParticipant localCallParticipant, @NonNull CallParticipant focusedParticipant) {
pictureInPictureExpansionHelper.expand(smallLocalRenderFrame, new PictureInPictureExpansionHelper.Callback() {
@Override
@@ -857,16 +881,15 @@ public class WebRtcCallView extends ConstraintLayout {
}
}
private void fadeInNewUiState(@NonNull Set<View> previouslyVisibleViewSet, boolean useSmallMargins) {
private void fadeInNewUiState(boolean useSmallMargins, boolean showSmallHeader) {
Transition transition = new AutoTransition().setDuration(TRANSITION_DURATION_MILLIS);
TransitionManager.endTransitions(parent);
TransitionManager.beginDelayedTransition(parent, transition);
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(parent);
for (View view : SetUtil.difference(previouslyVisibleViewSet, visibleViewSet)) {
for (View view : SetUtil.difference(allTimeVisibleViews, visibleViewSet)) {
constraintSet.setVisibility(view.getId(), ConstraintSet.GONE);
}
@@ -884,6 +907,10 @@ public class WebRtcCallView extends ConstraintLayout {
adjustParticipantsRecycler(constraintSet);
constraintSet.applyTo(parent);
if (showSmallHeader) {
smallHeaderConstraints.applyTo(toolbar);
}
}
private void adjustParticipantsRecycler(@NonNull ConstraintSet constraintSet) {

View File

@@ -112,7 +112,7 @@ public final class WebRtcControls {
}
boolean displayGroupMembersButton() {
return groupCallState.isAtLeast(GroupCallState.CONNECTING);
return (groupCallState.isAtLeast(GroupCallState.CONNECTING) && hasAtLeastOneRemote) || groupCallState.isAtLeast(GroupCallState.FULL);
}
boolean displayEndCall() {
@@ -175,6 +175,14 @@ public final class WebRtcControls {
return audioOutput;
}
boolean showSmallHeader() {
return isAtLeastOutgoing();
}
boolean showFullScreenShade() {
return isPreJoin() || isIncoming();
}
private boolean isError() {
return callState == CallState.ERROR;
}