Make group subtitles auto-update as names change.
This commit is contained in:
parent
69fd4f79db
commit
066892c11a
3 changed files with 48 additions and 11 deletions
|
@ -15,8 +15,6 @@ import androidx.annotation.Nullable;
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
import com.annimon.stream.Collectors;
|
|
||||||
import com.annimon.stream.Stream;
|
|
||||||
import com.bumptech.glide.RequestManager;
|
import com.bumptech.glide.RequestManager;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
|
@ -176,6 +174,11 @@ public class ConversationTitleView extends ConstraintLayout {
|
||||||
updateVerifiedSubtitleVisibility();
|
updateVerifiedSubtitleVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setGroupRecipientSubtitle(@Nullable String members) {
|
||||||
|
this.subtitle.setText(members);
|
||||||
|
updateSubtitleVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
private void setComposeTitle() {
|
private void setComposeTitle() {
|
||||||
this.title.setText(R.string.ConversationActivity_compose_message);
|
this.title.setText(R.string.ConversationActivity_compose_message);
|
||||||
this.subtitle.setText(null);
|
this.subtitle.setText(null);
|
||||||
|
@ -190,15 +193,6 @@ public class ConversationTitleView extends ConstraintLayout {
|
||||||
|
|
||||||
private void setGroupRecipientTitle(@NonNull Recipient recipient) {
|
private void setGroupRecipientTitle(@NonNull Recipient recipient) {
|
||||||
this.title.setText(recipient.getDisplayName(getContext()));
|
this.title.setText(recipient.getDisplayName(getContext()));
|
||||||
this.subtitle.setText(Stream.of(recipient.getParticipantIds())
|
|
||||||
.limit(10)
|
|
||||||
.map(Recipient::resolved)
|
|
||||||
.sorted((a, b) -> Boolean.compare(a.isSelf(), b.isSelf()))
|
|
||||||
.map(r -> r.isSelf() ? getResources().getString(R.string.ConversationTitleView_you)
|
|
||||||
: r.getDisplayName(getContext()))
|
|
||||||
.collect(Collectors.joining(", ")));
|
|
||||||
|
|
||||||
updateSubtitleVisibility();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setSelfTitle() {
|
private void setSelfTitle() {
|
||||||
|
|
|
@ -581,6 +581,7 @@ class ConversationFragment :
|
||||||
presentWallpaper(args.wallpaper)
|
presentWallpaper(args.wallpaper)
|
||||||
presentChatColors(args.chatColors)
|
presentChatColors(args.chatColors)
|
||||||
presentConversationTitle(viewModel.recipientSnapshot)
|
presentConversationTitle(viewModel.recipientSnapshot)
|
||||||
|
presentGroupConversationSubtitle(createGroupSubtitleString(viewModel.titleViewParticipantsSnapshot))
|
||||||
presentActionBarMenu()
|
presentActionBarMenu()
|
||||||
presentStoryRing()
|
presentStoryRing()
|
||||||
|
|
||||||
|
@ -865,6 +866,10 @@ class ConversationFragment :
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
|
private fun createGroupSubtitleString(members: List<Recipient>): String {
|
||||||
|
return members.joinToString(", ") { r -> if (r.isSelf) getString(R.string.ConversationTitleView_you) else r.getDisplayName(requireContext()) }
|
||||||
|
}
|
||||||
|
|
||||||
private fun observeConversationThread() {
|
private fun observeConversationThread() {
|
||||||
var firstRender = true
|
var firstRender = true
|
||||||
disposables += viewModel
|
disposables += viewModel
|
||||||
|
@ -924,6 +929,12 @@ class ConversationFragment :
|
||||||
.distinctUntilChanged { r1, r2 -> r1 === r2 || r1.hasSameContent(r2) }
|
.distinctUntilChanged { r1, r2 -> r1 === r2 || r1.hasSameContent(r2) }
|
||||||
.subscribeBy(onNext = this::onRecipientChanged)
|
.subscribeBy(onNext = this::onRecipientChanged)
|
||||||
|
|
||||||
|
disposables += viewModel.titleViewParticipants
|
||||||
|
.map { createGroupSubtitleString(it) }
|
||||||
|
.distinctUntilChanged()
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribeBy(onNext = this::presentGroupConversationSubtitle)
|
||||||
|
|
||||||
disposables += viewModel.scrollButtonState
|
disposables += viewModel.scrollButtonState
|
||||||
.subscribeBy(onNext = this::presentScrollButtons)
|
.subscribeBy(onNext = this::presentScrollButtons)
|
||||||
|
|
||||||
|
@ -1315,6 +1326,17 @@ class ConversationFragment :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun presentGroupConversationSubtitle(subtitle: String) {
|
||||||
|
val titleView = binding.conversationTitleView.root
|
||||||
|
|
||||||
|
if (subtitle.isBlank()) {
|
||||||
|
titleView.setGroupRecipientSubtitle(null)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
titleView.setGroupRecipientSubtitle(subtitle)
|
||||||
|
}
|
||||||
|
|
||||||
private fun presentConversationTitle(recipient: Recipient?) {
|
private fun presentConversationTitle(recipient: Recipient?) {
|
||||||
if (recipient == null) {
|
if (recipient == null) {
|
||||||
return
|
return
|
||||||
|
@ -1323,6 +1345,7 @@ class ConversationFragment :
|
||||||
val titleView = binding.conversationTitleView.root
|
val titleView = binding.conversationTitleView.root
|
||||||
|
|
||||||
titleView.setTitle(Glide.with(this), recipient)
|
titleView.setTitle(Glide.with(this), recipient)
|
||||||
|
|
||||||
if (recipient.expiresInSeconds > 0) {
|
if (recipient.expiresInSeconds > 0) {
|
||||||
titleView.showExpiring(recipient)
|
titleView.showExpiring(recipient)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -101,6 +101,17 @@ class ConversationViewModel(
|
||||||
get() = scrollButtonStateStore.state.unreadCount
|
get() = scrollButtonStateStore.state.unreadCount
|
||||||
|
|
||||||
val recipient: Observable<Recipient> = recipientRepository.conversationRecipient
|
val recipient: Observable<Recipient> = recipientRepository.conversationRecipient
|
||||||
|
val titleViewParticipants: Observable<List<Recipient>> = recipient.filter { it.isGroup }.switchMap { groupRecipient ->
|
||||||
|
val firstTenIds = groupRecipient.participantIds
|
||||||
|
.take(10)
|
||||||
|
.sortedBy { it == Recipient.self().id }
|
||||||
|
|
||||||
|
Observable.combineLatest(
|
||||||
|
firstTenIds.map { Recipient.observable(it) }
|
||||||
|
) { objects ->
|
||||||
|
objects.toList() as List<Recipient>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val _conversationThreadState: Subject<ConversationThreadState> = BehaviorSubject.create()
|
private val _conversationThreadState: Subject<ConversationThreadState> = BehaviorSubject.create()
|
||||||
val conversationThreadState: Single<ConversationThreadState> = _conversationThreadState.firstOrError()
|
val conversationThreadState: Single<ConversationThreadState> = _conversationThreadState.firstOrError()
|
||||||
|
@ -122,6 +133,10 @@ class ConversationViewModel(
|
||||||
var recipientSnapshot: Recipient? = null
|
var recipientSnapshot: Recipient? = null
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
@Volatile
|
||||||
|
var titleViewParticipantsSnapshot: List<Recipient> = emptyList()
|
||||||
|
private set
|
||||||
|
|
||||||
val isPushAvailable: Boolean
|
val isPushAvailable: Boolean
|
||||||
get() = recipientSnapshot?.isRegistered == true && Recipient.self().isRegistered
|
get() = recipientSnapshot?.isRegistered == true && Recipient.self().isRegistered
|
||||||
|
|
||||||
|
@ -167,6 +182,11 @@ class ConversationViewModel(
|
||||||
recipientSnapshot = it
|
recipientSnapshot = it
|
||||||
}
|
}
|
||||||
|
|
||||||
|
disposables += titleViewParticipants
|
||||||
|
.subscribeBy {
|
||||||
|
titleViewParticipantsSnapshot = it
|
||||||
|
}
|
||||||
|
|
||||||
val chatColorsDataObservable: Observable<ChatColorsDrawable.ChatColorsData> = Observable.combineLatest(
|
val chatColorsDataObservable: Observable<ChatColorsDrawable.ChatColorsData> = Observable.combineLatest(
|
||||||
recipient.map { it.chatColors }.distinctUntilChanged(),
|
recipient.map { it.chatColors }.distinctUntilChanged(),
|
||||||
chatBounds.distinctUntilChanged()
|
chatBounds.distinctUntilChanged()
|
||||||
|
|
Loading…
Add table
Reference in a new issue