Fix crash when opening group story replies.

This commit is contained in:
Greyson Parrelli 2024-02-05 16:30:54 -05:00
parent c8c4fdc65e
commit 2cf9fa0524
3 changed files with 10 additions and 85 deletions

View file

@ -1,63 +0,0 @@
package org.thoughtcrime.securesms.conversation.colors
import androidx.lifecycle.LiveData
import androidx.lifecycle.map
import androidx.lifecycle.switchMap
import com.annimon.stream.Stream
import org.signal.core.util.MapUtil
import org.thoughtcrime.securesms.conversation.colors.ChatColorsPalette.Names.all
import org.thoughtcrime.securesms.groups.GroupId
import org.thoughtcrime.securesms.groups.LiveGroup
import org.thoughtcrime.securesms.groups.ui.GroupMemberEntry.FullMember
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.util.DefaultValueLiveData
import java.util.Optional
object NameColors {
fun createSessionMembersCache(): MutableMap<GroupId, Set<Recipient>> {
return mutableMapOf()
}
fun getNameColorsMapLiveData(
recipientId: LiveData<RecipientId>,
sessionMemberCache: MutableMap<GroupId, Set<Recipient>>
): LiveData<Map<RecipientId, NameColor>> {
val recipient = recipientId.switchMap { r: RecipientId? -> Recipient.live(r!!).liveData }
val group = recipient.map { obj: Recipient -> obj.groupId }
val groupMembers = group.switchMap { g: Optional<GroupId> ->
g.map { groupId: GroupId -> this.getSessionGroupRecipients(groupId, sessionMemberCache) }
.orElseGet { DefaultValueLiveData(emptySet()) }
}
return groupMembers.map { members: Set<Recipient>? ->
val sorted = Stream.of(members)
.filter { member: Recipient? -> member != Recipient.self() }
.sortBy { obj: Recipient -> obj.requireStringId() }
.toList()
val names = all
val colors: MutableMap<RecipientId, NameColor> = HashMap()
for (i in sorted.indices) {
colors[sorted[i].id] = names[i % names.size]
}
colors
}
}
private fun getSessionGroupRecipients(groupId: GroupId, sessionMemberCache: MutableMap<GroupId, Set<Recipient>>): LiveData<Set<Recipient>> {
val fullMembers = LiveGroup(groupId)
.fullMembers
.map { members: List<FullMember>? ->
Stream.of(members)
.map { it.member }
.toList()
}
return fullMembers.map { currentMembership: List<Recipient>? ->
val cachedMembers: MutableSet<Recipient> = MapUtil.getOrDefault(sessionMemberCache, groupId, HashSet()).toMutableSet()
cachedMembers.addAll(currentMembership!!)
sessionMemberCache[groupId] = cachedMembers
cachedMembers
}
}
}

View file

@ -1,23 +1,19 @@
package org.thoughtcrime.securesms.stories.viewer.reply.group
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.schedulers.Schedulers
import org.signal.core.util.ThreadUtil
import org.signal.paging.ObservablePagedData
import org.signal.paging.PagedData
import org.signal.paging.PagingConfig
import org.signal.paging.PagingController
import org.thoughtcrime.securesms.conversation.colors.GroupAuthorNameColorHelper
import org.thoughtcrime.securesms.conversation.colors.NameColor
import org.thoughtcrime.securesms.conversation.colors.NameColors
import org.thoughtcrime.securesms.database.DatabaseObserver
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.database.model.MessageId
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
import org.thoughtcrime.securesms.groups.GroupId
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.recipients.RecipientId
class StoryGroupReplyRepository {
@ -55,18 +51,12 @@ class StoryGroupReplyRepository {
}
}
fun getNameColorsMap(storyId: Long, sessionMemberCache: MutableMap<GroupId, Set<Recipient>>): Observable<Map<RecipientId, NameColor>> {
return Single.fromCallable { SignalDatabase.messages.getMessageRecord(storyId).fromRecipient.id }
.subscribeOn(Schedulers.io())
.flatMapObservable { recipientId ->
Observable.create<Map<RecipientId, NameColor>?> { emitter ->
val nameColorsMapLiveData = NameColors.getNameColorsMapLiveData(MutableLiveData(recipientId), sessionMemberCache)
val observer = Observer<Map<RecipientId, NameColor>> { emitter.onNext(it) }
ThreadUtil.postToMain { nameColorsMapLiveData.observeForever(observer) }
emitter.setCancellable { ThreadUtil.postToMain { nameColorsMapLiveData.removeObserver(observer) } }
}.subscribeOn(Schedulers.io())
fun getNameColorsMap(storyId: Long): Observable<Map<RecipientId, NameColor>> {
return Single
.fromCallable {
val groupId = SignalDatabase.messages.getMessageRecord(storyId).toRecipient.groupId
GroupAuthorNameColorHelper().getColorMap(groupId.get())
}
.toObservable()
}
}

View file

@ -2,20 +2,17 @@ package org.thoughtcrime.securesms.stories.viewer.reply.group
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.kotlin.plusAssign
import io.reactivex.rxjava3.kotlin.subscribeBy
import org.signal.paging.ProxyPagingController
import org.thoughtcrime.securesms.conversation.colors.NameColors
import org.thoughtcrime.securesms.database.model.MessageId
import org.thoughtcrime.securesms.groups.GroupId
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.util.rx.RxStore
class StoryGroupReplyViewModel(storyId: Long, repository: StoryGroupReplyRepository) : ViewModel() {
private val sessionMemberCache: MutableMap<GroupId, Set<Recipient>> = NameColors.createSessionMembersCache()
private val store = RxStore(StoryGroupReplyState())
private val disposables = CompositeDisposable()
@ -41,7 +38,8 @@ class StoryGroupReplyViewModel(storyId: Long, repository: StoryGroupReplyReposit
}
}
disposables += repository.getNameColorsMap(storyId, sessionMemberCache)
disposables += repository.getNameColorsMap(storyId)
.observeOn(AndroidSchedulers.mainThread())
.subscribeBy { nameColors ->
store.update { state ->
state.copy(nameColors = nameColors)