diff --git a/app/src/main/java/org/thoughtcrime/securesms/WebRtcCallActivity.java b/app/src/main/java/org/thoughtcrime/securesms/WebRtcCallActivity.java index 5f6a0901f..8fc40faa7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/WebRtcCallActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/WebRtcCallActivity.java @@ -283,6 +283,10 @@ public class WebRtcCallActivity extends AppCompatActivity implements SafetyNumbe videoTooltip.dismiss(); videoTooltip = null; } + } else if (event instanceof WebRtcCallViewModel.Event.ShowSpeakerViewHint) { + callScreen.showSpeakerViewHint(); + } else if (event instanceof WebRtcCallViewModel.Event.HideSpeakerViewHint) { + callScreen.hideSpeakerViewHint(); } else { throw new IllegalArgumentException("Unknown event: " + event); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/WebRtcCallView.java b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/WebRtcCallView.java index f66374f86..ef8c60e81 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/WebRtcCallView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/WebRtcCallView.java @@ -8,6 +8,7 @@ import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.view.ViewStub; import android.view.animation.Animation; import android.widget.FrameLayout; import android.widget.ImageView; @@ -47,6 +48,7 @@ import org.thoughtcrime.securesms.ringrtc.CameraState; import org.thoughtcrime.securesms.util.BlurTransformation; import org.thoughtcrime.securesms.util.SetUtil; import org.thoughtcrime.securesms.util.ViewUtil; +import org.thoughtcrime.securesms.util.views.Stub; import org.webrtc.RendererCommon; import org.whispersystems.signalservice.api.messages.calls.HangupMessage; @@ -93,6 +95,7 @@ public class WebRtcCallView extends FrameLayout { private Toolbar toolbar; private MaterialButton startCall; private TextView participantCount; + private Stub groupCallSpeakerHint; private int pagerBottomMarginDp; private boolean controlsVisible = true; @@ -148,6 +151,7 @@ public class WebRtcCallView extends FrameLayout { callParticipantsRecycler = findViewById(R.id.call_screen_participants_recycler); toolbar = findViewById(R.id.call_screen_toolbar); startCall = findViewById(R.id.call_screen_start_call_start_call); + groupCallSpeakerHint = new Stub<>(findViewById(R.id.call_screen_group_call_speaker_hint)); View topGradient = findViewById(R.id.call_screen_header_gradient); View decline = findViewById(R.id.call_screen_decline_call); @@ -503,6 +507,16 @@ public class WebRtcCallView extends FrameLayout { return videoToggle; } + public void showSpeakerViewHint() { + groupCallSpeakerHint.get(); + } + + public void hideSpeakerViewHint() { + if (groupCallSpeakerHint.resolved()) { + groupCallSpeakerHint.get().setVisibility(View.GONE); + } + } + private void animatePipToLargeRectangle() { ResizeAnimation animation = new ResizeAnimation(smallLocalRenderFrame, ViewUtil.dpToPx(90), ViewUtil.dpToPx(160)); animation.setDuration(PIP_RESIZE_DURATION); diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/WebRtcCallViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/WebRtcCallViewModel.java index 1969565ab..249e7ad04 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/WebRtcCallViewModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/webrtc/WebRtcCallViewModel.java @@ -19,6 +19,7 @@ import org.thoughtcrime.securesms.events.CallParticipantId; import org.thoughtcrime.securesms.events.WebRtcViewModel; import org.thoughtcrime.securesms.groups.LiveGroup; import org.thoughtcrime.securesms.groups.ui.GroupMemberEntry; +import org.thoughtcrime.securesms.keyvalue.SignalStore; import org.thoughtcrime.securesms.recipients.LiveRecipient; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.recipients.RecipientId; @@ -122,6 +123,10 @@ public class WebRtcCallViewModel extends ViewModel { public void setIsViewingFocusedParticipant(@NonNull CallParticipantsState.SelectedPage page) { //noinspection ConstantConditions participantsState.setValue(CallParticipantsState.update(participantsState.getValue(), page)); + if (page == CallParticipantsState.SelectedPage.FOCUSED) { + SignalStore.tooltips().markGroupCallSpeakerViewSeen(); + events.setValue(new Event.HideSpeakerViewHint()); + } } public void onDismissedVideoTooltip() { @@ -179,6 +184,14 @@ public class WebRtcCallViewModel extends ViewModel { canDisplayTooltipIfNeeded = false; events.setValue(new Event.ShowVideoTooltip()); } + + //noinspection ConstantConditions + if (!isInPipMode.getValue() && + webRtcViewModel.getRemoteParticipants().size() > 1 && + webRtcViewModel.getGroupState().isConnected() && + !SignalStore.tooltips().hasSeenGroupCallSpeakerView()) { + events.setValue(new Event.ShowSpeakerViewHint()); + } } private boolean containsPlaceholders(@NonNull List callParticipants) { @@ -312,6 +325,12 @@ public class WebRtcCallViewModel extends ViewModel { public static class DismissVideoTooltip extends Event { } + public static class ShowSpeakerViewHint extends Event { + } + + public static class HideSpeakerViewHint extends Event { + } + public static class StartCall extends Event { private final boolean isVideoCall; diff --git a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/TooltipValues.java b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/TooltipValues.java index a158b769f..6c0b578a0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/keyvalue/TooltipValues.java +++ b/app/src/main/java/org/thoughtcrime/securesms/keyvalue/TooltipValues.java @@ -4,7 +4,8 @@ import androidx.annotation.NonNull; public class TooltipValues extends SignalStoreValues { - private static final String BLUR_HUD_ICON = "tooltip.blur_hud_icon"; + private static final String BLUR_HUD_ICON = "tooltip.blur_hud_icon"; + private static final String GROUP_CALL_SPEAKER_VIEW = "tooltip.group_call_speaker_view"; TooltipValues(@NonNull KeyValueStore store) { super(store); @@ -21,4 +22,12 @@ public class TooltipValues extends SignalStoreValues { public void markBlurHudIconTooltipSeen() { putBoolean(BLUR_HUD_ICON, true); } + + public boolean hasSeenGroupCallSpeakerView() { + return getBoolean(GROUP_CALL_SPEAKER_VIEW, false); + } + + public void markGroupCallSpeakerViewSeen() { + putBoolean(GROUP_CALL_SPEAKER_VIEW, true); + } } diff --git a/app/src/main/res/drawable/ic_arrow_up_16.xml b/app/src/main/res/drawable/ic_arrow_up_16.xml new file mode 100644 index 000000000..c3b4dd505 --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_up_16.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/group_call_speaker_hint.xml b/app/src/main/res/layout/group_call_speaker_hint.xml new file mode 100644 index 000000000..5bb5e6e0c --- /dev/null +++ b/app/src/main/res/layout/group_call_speaker_hint.xml @@ -0,0 +1,23 @@ + + + + + + diff --git a/app/src/main/res/layout/webrtc_call_view.xml b/app/src/main/res/layout/webrtc_call_view.xml index 9552f2193..683f3bd07 100644 --- a/app/src/main/res/layout/webrtc_call_view.xml +++ b/app/src/main/res/layout/webrtc_call_view.xml @@ -316,6 +316,17 @@ + + New safety number Accept End call + Swipe up to change views Decline