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

View File

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