Hide join group call for inactive groups.

This commit is contained in:
Alan Evans 2020-12-08 14:44:21 -04:00 committed by Greyson Parrelli
parent 944a180b68
commit 3949f4fd45
4 changed files with 72 additions and 38 deletions

View file

@ -2134,7 +2134,7 @@ public class ConversationActivity extends PassphraseRequiredActivity
joinGroupCallButton.setVisibility(hasActiveCall ? View.VISIBLE : View.GONE);
});
groupCallViewModel.canJoinGroupCall().observe(this, canJoin -> joinGroupCallButton.setText(canJoin ? R.string.ConversationActivity_join : R.string.ConversationActivity_full));
groupCallViewModel.groupCallHasCapacity().observe(this, hasCapacity -> joinGroupCallButton.setText(hasCapacity ? R.string.ConversationActivity_join : R.string.ConversationActivity_full));
}
private void showStickerIntroductionTooltip() {

View file

@ -50,15 +50,18 @@ public final class ConversationUpdateItem extends LinearLayout
private TextView body;
private TextView actionButton;
private LiveRecipient sender;
private ConversationMessage conversationMessage;
private Recipient conversationRecipient;
private Optional<MessageRecord> nextMessageRecord;
private MessageRecord messageRecord;
private LiveData<Spannable> displayBody;
private EventListener eventListener;
private final UpdateObserver updateObserver = new UpdateObserver();
private final SenderObserver senderObserver = new SenderObserver();
private final PresentOnChange presentOnChange = new PresentOnChange();
private final RecipientObserverManager senderObserver = new RecipientObserverManager(presentOnChange);
private final RecipientObserverManager groupObserver = new RecipientObserverManager(presentOnChange);
public ConversationUpdateItem(Context context) {
super(context);
@ -91,7 +94,7 @@ public final class ConversationUpdateItem extends LinearLayout
{
this.batchSelected = batchSelected;
bind(lifecycleOwner, conversationMessage, nextMessageRecord);
bind(lifecycleOwner, conversationMessage, nextMessageRecord, conversationRecipient);
}
@Override
@ -106,20 +109,26 @@ public final class ConversationUpdateItem extends LinearLayout
private void bind(@NonNull LifecycleOwner lifecycleOwner,
@NonNull ConversationMessage conversationMessage,
@NonNull Optional<MessageRecord> nextMessageRecord)
@NonNull Optional<MessageRecord> nextMessageRecord,
@NonNull Recipient conversationRecipient)
{
this.conversationMessage = conversationMessage;
this.messageRecord = conversationMessage.getMessageRecord();
this.nextMessageRecord = nextMessageRecord;
this.conversationMessage = conversationMessage;
this.messageRecord = conversationMessage.getMessageRecord();
this.nextMessageRecord = nextMessageRecord;
this.conversationRecipient = conversationRecipient;
observeSender(lifecycleOwner, messageRecord.getIndividualRecipient());
senderObserver.observe(lifecycleOwner, messageRecord.getIndividualRecipient());
if (conversationRecipient.isActiveGroup() && conversationMessage.getMessageRecord().isGroupCall()) {
groupObserver.observe(lifecycleOwner, conversationRecipient);
} else {
groupObserver.observe(lifecycleOwner, null);
}
UpdateDescription updateDescription = Objects.requireNonNull(messageRecord.getUpdateDisplayBody(getContext()));
LiveData<Spannable> liveUpdateMessage = LiveUpdateMessage.fromMessageDescription(getContext(), updateDescription, ContextCompat.getColor(getContext(), R.color.conversation_item_update_text_color));
LiveData<Spannable> spannableMessage = loading(liveUpdateMessage);
present(conversationMessage, nextMessageRecord);
observeDisplayBody(lifecycleOwner, spannableMessage);
}
@ -132,16 +141,31 @@ public final class ConversationUpdateItem extends LinearLayout
public void unbind() {
}
private void observeSender(@NonNull LifecycleOwner lifecycleOwner, @Nullable Recipient recipient) {
if (sender != null) {
sender.getLiveData().removeObserver(senderObserver);
static final class RecipientObserverManager {
private final Observer<Recipient> recipientObserver;
private LiveRecipient recipient;
RecipientObserverManager(@NonNull Observer<Recipient> observer){
this.recipientObserver = observer;
}
if (recipient != null) {
sender = recipient.live();
sender.getLiveData().observe(lifecycleOwner, senderObserver);
} else {
sender = null;
public void observe(@NonNull LifecycleOwner lifecycleOwner, @Nullable Recipient recipient) {
if (this.recipient != null) {
this.recipient.getLiveData().removeObserver(recipientObserver);
}
if (recipient != null) {
this.recipient = recipient.live();
this.recipient.getLiveData().observe(lifecycleOwner, recipientObserver);
} else {
this.recipient = null;
}
}
@NonNull Recipient getObservedRecipient() {
return recipient.get();
}
}
@ -168,7 +192,7 @@ public final class ConversationUpdateItem extends LinearLayout
}
}
private void present(ConversationMessage conversationMessage, @NonNull Optional<MessageRecord> nextMessageRecord) {
private void present(ConversationMessage conversationMessage, @NonNull Optional<MessageRecord> nextMessageRecord, @NonNull Recipient conversationRecipient) {
if (batchSelected.contains(conversationMessage)) setSelected(true);
else setSelected(false);
@ -195,7 +219,7 @@ public final class ConversationUpdateItem extends LinearLayout
}
}
if (text != 0) {
if (text != 0 && conversationRecipient.isGroup() && conversationRecipient.isActiveGroup()) {
actionButton.setText(text);
actionButton.setVisibility(VISIBLE);
actionButton.setOnClickListener(v -> {
@ -218,11 +242,14 @@ public final class ConversationUpdateItem extends LinearLayout
super.setOnClickListener(new InternalClickListener(l));
}
private final class SenderObserver implements Observer<Recipient> {
private final class PresentOnChange implements Observer<Recipient> {
@Override
public void onChanged(Recipient recipient) {
present(conversationMessage, nextMessageRecord);
if (recipient.getId() == conversationRecipient.getId()) {
conversationRecipient = recipient;
}
present(conversationMessage, nextMessageRecord, conversationRecipient);
}
}
@ -253,7 +280,7 @@ public final class ConversationUpdateItem extends LinearLayout
return;
}
final Recipient sender = ConversationUpdateItem.this.sender.get();
final Recipient sender = ConversationUpdateItem.this.senderObserver.getObservedRecipient();
IdentityUtil.getRemoteIdentityKey(getContext(), sender).addListener(new ListenableFuture.Listener<Optional<IdentityRecord>>() {
@Override

View file

@ -16,6 +16,7 @@ import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.ringrtc.RemotePeer;
import org.thoughtcrime.securesms.service.WebRtcCallService;
import org.thoughtcrime.securesms.util.FeatureFlags;
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
import java.util.Objects;
@ -23,31 +24,37 @@ public class GroupCallViewModel extends ViewModel {
private static final String TAG = Log.tag(GroupCallViewModel.class);
private final MutableLiveData<Boolean> activeGroupCall;
private final MutableLiveData<Boolean> canJoin;
private final MutableLiveData<Boolean> activeGroup;
private final MutableLiveData<Boolean> ongoingGroupCall;
private final LiveData<Boolean> activeGroupCall;
private final MutableLiveData<Boolean> groupCallHasCapacity;
private @Nullable Recipient currentRecipient;
GroupCallViewModel() {
this.activeGroupCall = new MutableLiveData<>(false);
this.canJoin = new MutableLiveData<>(false);
this.activeGroup = new MutableLiveData<>(false);
this.ongoingGroupCall = new MutableLiveData<>(false);
this.groupCallHasCapacity = new MutableLiveData<>(false);
this.activeGroupCall = LiveDataUtil.combineLatest(activeGroup, ongoingGroupCall, (active, ongoing) -> active && ongoing);
}
public @NonNull LiveData<Boolean> hasActiveGroupCall() {
return activeGroupCall;
}
public @NonNull LiveData<Boolean> canJoinGroupCall() {
return canJoin;
public @NonNull LiveData<Boolean> groupCallHasCapacity() {
return groupCallHasCapacity;
}
public void onRecipientChange(@NonNull Context context, @Nullable Recipient recipient) {
activeGroup.postValue(recipient != null && recipient.isActiveGroup());
if (Objects.equals(currentRecipient, recipient)) {
return;
}
activeGroupCall.postValue(false);
canJoin.postValue(false);
ongoingGroupCall.postValue(false);
groupCallHasCapacity.postValue(false);
currentRecipient = recipient;
@ -67,10 +74,10 @@ public class GroupCallViewModel extends ViewModel {
public void onGroupCallPeekEvent(@NonNull GroupCallPeekEvent groupCallPeekEvent) {
if (isGroupCallCapable(currentRecipient) && groupCallPeekEvent.getGroupRecipientId().equals(currentRecipient.getId())) {
Log.i(TAG, "update UI with call event: active call: " + groupCallPeekEvent.hasActiveCall() + " canJoin: " + groupCallPeekEvent.canJoinCall());
Log.i(TAG, "update UI with call event: ongoing call: " + groupCallPeekEvent.isOngoing() + " hasCapacity: " + groupCallPeekEvent.callHasCapacity());
activeGroupCall.postValue(groupCallPeekEvent.hasActiveCall());
canJoin.postValue(groupCallPeekEvent.canJoinCall());
ongoingGroupCall.postValue(groupCallPeekEvent.isOngoing());
groupCallHasCapacity.postValue(groupCallPeekEvent.callHasCapacity());
} else {
Log.i(TAG, "Ignore call event for different recipient.");
}

View file

@ -22,11 +22,11 @@ public final class GroupCallPeekEvent {
return groupRecipientId;
}
public boolean hasActiveCall() {
public boolean isOngoing() {
return eraId != null && deviceCount > 0;
}
public boolean canJoinCall() {
return hasActiveCall() && deviceCount < deviceLimit;
public boolean callHasCapacity() {
return isOngoing() && deviceCount < deviceLimit;
}
}