mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-22 01:40:07 +01:00
Display member label on recipient details sheet.
This commit is contained in:
committed by
Greyson Parrelli
parent
fae4ca91bd
commit
d5b2f4fdd3
@@ -36,6 +36,7 @@ import org.thoughtcrime.securesms.components.settings.conversation.preferences.B
|
||||
import org.thoughtcrime.securesms.conversation.v2.data.AvatarDownloadStateCache
|
||||
import org.thoughtcrime.securesms.fonts.SignalSymbols
|
||||
import org.thoughtcrime.securesms.groups.GroupId
|
||||
import org.thoughtcrime.securesms.groups.memberlabel.MemberLabelPillView
|
||||
import org.thoughtcrime.securesms.nicknames.NicknameActivity
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.recipients.RecipientExporter
|
||||
@@ -108,7 +109,8 @@ class RecipientBottomSheetDialogFragment : FixedRoundedCornerBottomSheetDialogFr
|
||||
|
||||
val avatar: AvatarView = view.findViewById(R.id.rbs_recipient_avatar)
|
||||
val fullName: TextView = view.findViewById(R.id.rbs_full_name)
|
||||
val about: TextView = view.findViewById(R.id.rbs_about)
|
||||
val memberLabelView: MemberLabelPillView = view.findViewById(R.id.rbs_member_label)
|
||||
val aboutView: TextView = view.findViewById(R.id.rbs_about)
|
||||
val nickname: TextView = view.findViewById(R.id.rbs_nickname_button)
|
||||
val blockButton: TextView = view.findViewById(R.id.rbs_block_button)
|
||||
val unblockButton: TextView = view.findViewById(R.id.rbs_unblock_button)
|
||||
@@ -148,6 +150,7 @@ class RecipientBottomSheetDialogFragment : FixedRoundedCornerBottomSheetDialogFr
|
||||
AvatarDownloadStateCache.forRecipient(recipient.id).collect {
|
||||
when (it) {
|
||||
AvatarDownloadStateCache.DownloadState.NONE -> {}
|
||||
|
||||
AvatarDownloadStateCache.DownloadState.IN_PROGRESS -> {
|
||||
if (inProgress) {
|
||||
return@collect
|
||||
@@ -159,12 +162,14 @@ class RecipientBottomSheetDialogFragment : FixedRoundedCornerBottomSheetDialogFr
|
||||
delay(LOADING_DELAY)
|
||||
progressBar.visible = AvatarDownloadStateCache.getDownloadState(recipient) == AvatarDownloadStateCache.DownloadState.IN_PROGRESS
|
||||
}
|
||||
|
||||
AvatarDownloadStateCache.DownloadState.FINISHED -> {
|
||||
AvatarDownloadStateCache.set(recipient, AvatarDownloadStateCache.DownloadState.NONE)
|
||||
viewModel.refreshGroupId(groupId)
|
||||
inProgress = false
|
||||
progressBar.visible = false
|
||||
}
|
||||
|
||||
AvatarDownloadStateCache.DownloadState.FAILED -> {
|
||||
AvatarDownloadStateCache.set(recipient, AvatarDownloadStateCache.DownloadState.NONE)
|
||||
avatar.displayGradientBlur(recipient)
|
||||
@@ -256,18 +261,6 @@ class RecipientBottomSheetDialogFragment : FixedRoundedCornerBottomSheetDialogFr
|
||||
fullName.text = name
|
||||
}
|
||||
|
||||
var aboutText = recipient.combinedAboutAndEmoji
|
||||
if (recipient.isReleaseNotes) {
|
||||
aboutText = getString(R.string.ReleaseNotes__signal_release_notes_and_news)
|
||||
}
|
||||
|
||||
if (!aboutText.isNullOrEmpty()) {
|
||||
about.text = aboutText
|
||||
about.visible = true
|
||||
} else {
|
||||
about.visible = false
|
||||
}
|
||||
|
||||
noteToSelfDescription.visible = recipient.isSelf
|
||||
|
||||
if (RecipientUtil.isBlockable(recipient)) {
|
||||
@@ -339,6 +332,10 @@ class RecipientBottomSheetDialogFragment : FixedRoundedCornerBottomSheetDialogFr
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.recipientDetails.observe(viewLifecycleOwner) { state ->
|
||||
updateRecipientDetails(state, memberLabelView, aboutView)
|
||||
}
|
||||
|
||||
viewModel.canAddToAGroup.observe(getViewLifecycleOwner()) { canAdd: Boolean ->
|
||||
addToGroupButton.setText(if (groupId == null) R.string.RecipientBottomSheet_add_to_a_group else R.string.RecipientBottomSheet_add_to_another_group)
|
||||
addToGroupButton.visible = canAdd
|
||||
@@ -449,6 +446,31 @@ class RecipientBottomSheetDialogFragment : FixedRoundedCornerBottomSheetDialogFr
|
||||
animator.start()
|
||||
}
|
||||
|
||||
private fun updateRecipientDetails(
|
||||
state: RecipientDetailsState,
|
||||
memberLabelView: MemberLabelPillView,
|
||||
aboutView: TextView
|
||||
) {
|
||||
when {
|
||||
state.memberLabel != null -> {
|
||||
memberLabelView.setLabel(state.memberLabel.label, state.memberLabel.tintColor)
|
||||
memberLabelView.visible = true
|
||||
aboutView.visible = false
|
||||
}
|
||||
|
||||
!state.aboutText.isNullOrBlank() -> {
|
||||
aboutView.text = state.aboutText
|
||||
aboutView.visible = true
|
||||
memberLabelView.visible = false
|
||||
}
|
||||
|
||||
else -> {
|
||||
memberLabelView.visible = false
|
||||
aboutView.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface Callback {
|
||||
fun onRecipientBottomSheetDismissed()
|
||||
fun onMessageClicked()
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.thoughtcrime.securesms.recipients.ui.bottomsheet
|
||||
|
||||
import androidx.annotation.ColorInt
|
||||
import org.thoughtcrime.securesms.groups.memberlabel.MemberLabel
|
||||
|
||||
data class RecipientDetailsState(
|
||||
val memberLabel: StyledMemberLabel?,
|
||||
val aboutText: String?
|
||||
)
|
||||
|
||||
data class StyledMemberLabel(
|
||||
val label: MemberLabel,
|
||||
@param:ColorInt val tintColor: Int
|
||||
)
|
||||
@@ -21,18 +21,23 @@ import org.signal.core.util.concurrent.SignalExecutors;
|
||||
import org.thoughtcrime.securesms.BlockUnblockDialog;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.components.settings.conversation.ConversationSettingsActivity;
|
||||
import org.thoughtcrime.securesms.conversation.colors.Colorizer;
|
||||
import org.thoughtcrime.securesms.database.GroupTable;
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||
import org.thoughtcrime.securesms.database.model.GroupRecord;
|
||||
import org.thoughtcrime.securesms.database.model.IdentityRecord;
|
||||
import org.thoughtcrime.securesms.database.model.StoryViewState;
|
||||
import org.thoughtcrime.securesms.groups.GroupId;
|
||||
import org.thoughtcrime.securesms.groups.LiveGroup;
|
||||
import org.thoughtcrime.securesms.groups.memberlabel.MemberLabel;
|
||||
import org.thoughtcrime.securesms.groups.memberlabel.MemberLabelRepository;
|
||||
import org.thoughtcrime.securesms.groups.ui.GroupChangeFailureReason;
|
||||
import org.thoughtcrime.securesms.groups.ui.GroupErrors;
|
||||
import org.thoughtcrime.securesms.groups.ui.addtogroup.AddToGroupsActivity;
|
||||
import org.thoughtcrime.securesms.jobs.AvatarGroupsV2DownloadJob;
|
||||
import org.thoughtcrime.securesms.jobs.RetrieveProfileAvatarJob;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.recipients.LiveRecipient;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||
@@ -44,6 +49,7 @@ import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
|
||||
import org.thoughtcrime.securesms.verify.VerifyIdentityActivity;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import kotlin.Pair;
|
||||
|
||||
@@ -52,16 +58,17 @@ import io.reactivex.rxjava3.disposables.Disposable;
|
||||
|
||||
final class RecipientDialogViewModel extends ViewModel {
|
||||
|
||||
private final Context context;
|
||||
private final RecipientDialogRepository recipientDialogRepository;
|
||||
private final LiveData<Recipient> recipient;
|
||||
private final MutableLiveData<IdentityRecord> identity;
|
||||
private final LiveData<AdminActionStatus> adminActionStatus;
|
||||
private final LiveData<Boolean> canAddToAGroup;
|
||||
private final MutableLiveData<Boolean> adminActionBusy;
|
||||
private final MutableLiveData<StoryViewState> storyViewState;
|
||||
private final CompositeDisposable disposables;
|
||||
private final boolean isDeprecatedOrUnregistered;
|
||||
private final Context context;
|
||||
private final RecipientDialogRepository recipientDialogRepository;
|
||||
private final LiveData<Recipient> recipient;
|
||||
private final MutableLiveData<IdentityRecord> identity;
|
||||
private final LiveData<AdminActionStatus> adminActionStatus;
|
||||
private final LiveData<Boolean> canAddToAGroup;
|
||||
private final MutableLiveData<Boolean> adminActionBusy;
|
||||
private final MutableLiveData<StoryViewState> storyViewState;
|
||||
private final MutableLiveData<RecipientDetailsState> recipientDetailsState;
|
||||
private final CompositeDisposable disposables;
|
||||
private final boolean isDeprecatedOrUnregistered;
|
||||
private RecipientDialogViewModel(@NonNull Context context,
|
||||
@NonNull RecipientDialogRepository recipientDialogRepository)
|
||||
{
|
||||
@@ -70,12 +77,14 @@ final class RecipientDialogViewModel extends ViewModel {
|
||||
this.identity = new MutableLiveData<>();
|
||||
this.adminActionBusy = new MutableLiveData<>(false);
|
||||
this.storyViewState = new MutableLiveData<>();
|
||||
this.recipientDetailsState = new MutableLiveData<>();
|
||||
this.disposables = new CompositeDisposable();
|
||||
this.isDeprecatedOrUnregistered = SignalStore.misc().isClientDeprecated() || TextSecurePreferences.isUnauthorizedReceived(context);
|
||||
|
||||
boolean recipientIsSelf = recipientDialogRepository.getRecipientId().equals(Recipient.self().getId());
|
||||
|
||||
recipient = Recipient.live(recipientDialogRepository.getRecipientId()).getLiveData();
|
||||
final LiveRecipient liveRecipient = Recipient.live(recipientDialogRepository.getRecipientId());
|
||||
recipient = liveRecipient.getLiveData();
|
||||
|
||||
if (recipientDialogRepository.getGroupId() != null && recipientDialogRepository.getGroupId().isV2() && !recipientIsSelf) {
|
||||
LiveGroup source = new LiveGroup(recipientDialogRepository.getGroupId());
|
||||
@@ -114,6 +123,35 @@ final class RecipientDialogViewModel extends ViewModel {
|
||||
.subscribe(storyViewState::postValue);
|
||||
|
||||
disposables.add(storyViewStateDisposable);
|
||||
|
||||
Disposable recipientDisposable = liveRecipient.observable().subscribe(this::updateRecipientDetailsState);
|
||||
disposables.add(recipientDisposable);
|
||||
}
|
||||
|
||||
private void updateRecipientDetailsState(@NonNull Recipient recipient) {
|
||||
GroupId groupId = recipientDialogRepository.getGroupId();
|
||||
String aboutText = recipient.isReleaseNotes() ? context.getString(R.string.ReleaseNotes__signal_release_notes_and_news) : recipient.getCombinedAboutAndEmoji();
|
||||
|
||||
if (groupId != null && groupId.isV2() && recipient.isIndividual() && !recipient.isSelf()) {
|
||||
SignalExecutors.BOUNDED.execute(() -> {
|
||||
GroupId.V2 v2GroupId = (GroupId.V2) groupId;
|
||||
MemberLabel label = MemberLabelRepository.getInstance().getLabelJava(v2GroupId, recipient);
|
||||
StyledMemberLabel styledLabel = null;
|
||||
|
||||
if (label != null) {
|
||||
Colorizer colorizer = new Colorizer();
|
||||
Optional<GroupRecord> groupRecord = SignalDatabase.groups().getGroup(v2GroupId);
|
||||
if (groupRecord.isPresent()) {
|
||||
colorizer.onGroupMembershipChanged(groupRecord.get().requireV2GroupProperties().getMemberServiceIds());
|
||||
}
|
||||
styledLabel = new StyledMemberLabel(label, colorizer.getIncomingGroupSenderColor(context, recipient));
|
||||
}
|
||||
|
||||
recipientDetailsState.postValue(new RecipientDetailsState(styledLabel, aboutText));
|
||||
});
|
||||
} else {
|
||||
recipientDetailsState.setValue(new RecipientDetailsState(null, aboutText));
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void onCleared() {
|
||||
@@ -149,6 +187,10 @@ final class RecipientDialogViewModel extends ViewModel {
|
||||
return adminActionBusy;
|
||||
}
|
||||
|
||||
LiveData<RecipientDetailsState> getRecipientDetails() {
|
||||
return recipientDetailsState;
|
||||
}
|
||||
|
||||
void onNoteToSelfClicked(@NonNull Activity activity) {
|
||||
if (storyViewState.getValue() == null || storyViewState.getValue() == StoryViewState.NONE) {
|
||||
onMessageClicked(activity);
|
||||
|
||||
Reference in New Issue
Block a user