Show internal conversation settings for groups.

This commit is contained in:
Greyson Parrelli 2021-09-30 19:04:34 -04:00
parent 33ac48e771
commit 5115717f67
4 changed files with 106 additions and 84 deletions

View file

@ -314,18 +314,16 @@ class ConversationSettingsFragment : DSLSettingsFragment(
} }
} }
state.withRecipientSettingsState { recipientState -> if (state.displayInternalRecipientDetails) {
if (recipientState.displayInternalRecipientDetails) { customPref(
customPref( InternalPreference.Model(
InternalPreference.Model( recipient = state.recipient,
recipient = state.recipient, onInternalDetailsClicked = {
onInternalDetailsClicked = { val action = ConversationSettingsFragmentDirections.actionConversationSettingsFragmentToInternalDetailsSettingsFragment(state.recipient.id)
val action = ConversationSettingsFragmentDirections.actionConversationSettingsFragmentToInternalDetailsSettingsFragment(state.recipient.id) navController.navigate(action)
navController.navigate(action) }
}
)
) )
} )
} }
customPref( customPref(

View file

@ -16,6 +16,7 @@ data class ConversationSettingsState(
val canModifyBlockedState: Boolean = false, val canModifyBlockedState: Boolean = false,
val sharedMedia: Cursor? = null, val sharedMedia: Cursor? = null,
val sharedMediaIds: List<Long> = listOf(), val sharedMediaIds: List<Long> = listOf(),
val displayInternalRecipientDetails: Boolean = false,
private val sharedMediaLoaded: Boolean = false, private val sharedMediaLoaded: Boolean = false,
private val specificSettingsState: SpecificSettingsState, private val specificSettingsState: SpecificSettingsState,
) { ) {
@ -49,8 +50,7 @@ sealed class SpecificSettingsState {
val selfHasGroups: Boolean = false, val selfHasGroups: Boolean = false,
val canShowMoreGroupsInCommon: Boolean = false, val canShowMoreGroupsInCommon: Boolean = false,
val groupsInCommonExpanded: Boolean = false, val groupsInCommonExpanded: Boolean = false,
val contactLinkState: ContactLinkState = ContactLinkState.NONE, val contactLinkState: ContactLinkState = ContactLinkState.NONE
val displayInternalRecipientDetails: Boolean
) : SpecificSettingsState() { ) : SpecificSettingsState() {
override val isLoaded: Boolean = true override val isLoaded: Boolean = true

View file

@ -71,7 +71,8 @@ sealed class ConversationSettingsViewModel(
state.copy( state.copy(
sharedMedia = cursor.orNull(), sharedMedia = cursor.orNull(),
sharedMediaIds = ids, sharedMediaIds = ids,
sharedMediaLoaded = true sharedMediaLoaded = true,
displayInternalRecipientDetails = repository.isInternalRecipientDetailsEnabled()
) )
} else { } else {
cursor.orNull().ensureClosed() cursor.orNull().ensureClosed()
@ -121,9 +122,7 @@ sealed class ConversationSettingsViewModel(
private val repository: ConversationSettingsRepository private val repository: ConversationSettingsRepository
) : ConversationSettingsViewModel( ) : ConversationSettingsViewModel(
repository, repository,
SpecificSettingsState.RecipientSettingsState( SpecificSettingsState.RecipientSettingsState()
displayInternalRecipientDetails = repository.isInternalRecipientDetailsEnabled()
)
) { ) {
private val liveRecipient = Recipient.live(recipientId) private val liveRecipient = Recipient.live(recipientId)

View file

@ -1,5 +1,6 @@
package org.thoughtcrime.securesms.components.settings.conversation package org.thoughtcrime.securesms.components.settings.conversation
import android.content.Context
import android.graphics.Color import android.graphics.Color
import android.text.TextUtils import android.text.TextUtils
import android.widget.Toast import android.widget.Toast
@ -16,6 +17,7 @@ import org.thoughtcrime.securesms.components.settings.DSLSettingsText
import org.thoughtcrime.securesms.components.settings.configure import org.thoughtcrime.securesms.components.settings.configure
import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.DatabaseFactory
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.Recipient
import org.thoughtcrime.securesms.recipients.RecipientForeverObserver import org.thoughtcrime.securesms.recipients.RecipientForeverObserver
import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.recipients.RecipientId
@ -57,12 +59,23 @@ class InternalConversationSettingsFragment : DSLSettingsFragment(
summary = DSLSettingsText.from(recipient.id.serialize()) summary = DSLSettingsText.from(recipient.id.serialize())
) )
val uuid = recipient.uuid.transform(UUID::toString).or("null") if (!recipient.isGroup) {
longClickPref( val uuid = recipient.uuid.transform(UUID::toString).or("null")
title = DSLSettingsText.from("UUID"), longClickPref(
summary = DSLSettingsText.from(uuid), title = DSLSettingsText.from("UUID"),
onLongClick = { copyToClipboard(uuid) } summary = DSLSettingsText.from(uuid),
) onLongClick = { copyToClipboard(uuid) }
)
}
if (state.groupId != null) {
val groupId: String = state.groupId.toString()
longClickPref(
title = DSLSettingsText.from("GroupId"),
summary = DSLSettingsText.from(groupId),
onLongClick = { copyToClipboard(groupId) }
)
}
val threadId: String = if (state.threadId != null) state.threadId.toString() else "N/A" val threadId: String = if (state.threadId != null) state.threadId.toString() else "N/A"
longClickPref( longClickPref(
@ -71,72 +84,78 @@ class InternalConversationSettingsFragment : DSLSettingsFragment(
onLongClick = { copyToClipboard(threadId) } onLongClick = { copyToClipboard(threadId) }
) )
textPref( if (!recipient.isGroup) {
title = DSLSettingsText.from("Profile Name"), textPref(
summary = DSLSettingsText.from("[${recipient.profileName.givenName}] [${state.recipient.profileName.familyName}]") title = DSLSettingsText.from("Profile Name"),
) summary = DSLSettingsText.from("[${recipient.profileName.givenName}] [${state.recipient.profileName.familyName}]")
)
val profileKeyBase64 = recipient.profileKey?.let(Base64::encodeBytes) ?: "None" val profileKeyBase64 = recipient.profileKey?.let(Base64::encodeBytes) ?: "None"
longClickPref( longClickPref(
title = DSLSettingsText.from("Profile Key (Base64)"), title = DSLSettingsText.from("Profile Key (Base64)"),
summary = DSLSettingsText.from(profileKeyBase64), summary = DSLSettingsText.from(profileKeyBase64),
onLongClick = { copyToClipboard(profileKeyBase64) } onLongClick = { copyToClipboard(profileKeyBase64) }
) )
val profileKeyHex = recipient.profileKey?.let(Hex::toStringCondensed) ?: "" val profileKeyHex = recipient.profileKey?.let(Hex::toStringCondensed) ?: ""
longClickPref( longClickPref(
title = DSLSettingsText.from("Profile Key (Hex)"), title = DSLSettingsText.from("Profile Key (Hex)"),
summary = DSLSettingsText.from(profileKeyHex), summary = DSLSettingsText.from(profileKeyHex),
onLongClick = { copyToClipboard(profileKeyHex) } onLongClick = { copyToClipboard(profileKeyHex) }
) )
textPref( textPref(
title = DSLSettingsText.from("Sealed Sender Mode"), title = DSLSettingsText.from("Sealed Sender Mode"),
summary = DSLSettingsText.from(recipient.unidentifiedAccessMode.toString()) summary = DSLSettingsText.from(recipient.unidentifiedAccessMode.toString())
) )
}
textPref( textPref(
title = DSLSettingsText.from("Profile Sharing (AKA \"Whitelisted\")"), title = DSLSettingsText.from("Profile Sharing (AKA \"Whitelisted\")"),
summary = DSLSettingsText.from(recipient.isProfileSharing.toString()) summary = DSLSettingsText.from(recipient.isProfileSharing.toString())
) )
textPref( if (!recipient.isGroup) {
title = DSLSettingsText.from("Capabilities"), textPref(
summary = DSLSettingsText.from(buildCapabilitySpan(recipient)) title = DSLSettingsText.from("Capabilities"),
) summary = DSLSettingsText.from(buildCapabilitySpan(recipient))
)
}
sectionHeaderPref(DSLSettingsText.from("Actions")) if (!recipient.isGroup) {
sectionHeaderPref(DSLSettingsText.from("Actions"))
clickPref( clickPref(
title = DSLSettingsText.from("Disable Profile Sharing"), title = DSLSettingsText.from("Disable Profile Sharing"),
summary = DSLSettingsText.from("Clears profile sharing/whitelisted status, which should cause the Message Request UI to show."), summary = DSLSettingsText.from("Clears profile sharing/whitelisted status, which should cause the Message Request UI to show."),
onClick = { onClick = {
MaterialAlertDialogBuilder(requireContext()) MaterialAlertDialogBuilder(requireContext())
.setTitle("Are you sure?") .setTitle("Are you sure?")
.setNegativeButton(android.R.string.cancel) { d, _ -> d.dismiss() } .setNegativeButton(android.R.string.cancel) { d, _ -> d.dismiss() }
.setPositiveButton(android.R.string.ok) { _, _ -> DatabaseFactory.getRecipientDatabase(requireContext()).setProfileSharing(recipient.id, false) } .setPositiveButton(android.R.string.ok) { _, _ -> DatabaseFactory.getRecipientDatabase(requireContext()).setProfileSharing(recipient.id, false) }
.show() .show()
} }
) )
clickPref( clickPref(
title = DSLSettingsText.from("Delete Session"), title = DSLSettingsText.from("Delete Session"),
summary = DSLSettingsText.from("Deletes the session, essentially guaranteeing an encryption error if they send you a message."), summary = DSLSettingsText.from("Deletes the session, essentially guaranteeing an encryption error if they send you a message."),
onClick = { onClick = {
MaterialAlertDialogBuilder(requireContext()) MaterialAlertDialogBuilder(requireContext())
.setTitle("Are you sure?") .setTitle("Are you sure?")
.setNegativeButton(android.R.string.cancel) { d, _ -> d.dismiss() } .setNegativeButton(android.R.string.cancel) { d, _ -> d.dismiss() }
.setPositiveButton(android.R.string.ok) { _, _ -> .setPositiveButton(android.R.string.ok) { _, _ ->
if (recipient.hasUuid()) { if (recipient.hasUuid()) {
DatabaseFactory.getSessionDatabase(context).deleteAllFor(recipient.requireUuid().toString()) DatabaseFactory.getSessionDatabase(context).deleteAllFor(recipient.requireUuid().toString())
}
if (recipient.hasE164()) {
DatabaseFactory.getSessionDatabase(context).deleteAllFor(recipient.requireE164())
}
} }
if (recipient.hasE164()) { .show()
DatabaseFactory.getSessionDatabase(context).deleteAllFor(recipient.requireE164()) }
} )
} }
.show()
}
)
} }
} }
@ -171,7 +190,13 @@ class InternalConversationSettingsFragment : DSLSettingsFragment(
val recipientId: RecipientId val recipientId: RecipientId
) : ViewModel(), RecipientForeverObserver { ) : ViewModel(), RecipientForeverObserver {
private val store = Store(InternalState(Recipient.resolved(recipientId), null)) private val store = Store(
InternalState(
recipient = Recipient.resolved(recipientId),
threadId = null,
groupId = null
)
)
val state = store.stateLiveData val state = store.stateLiveData
val liveRecipient = Recipient.live(recipientId) val liveRecipient = Recipient.live(recipientId)
@ -180,16 +205,15 @@ class InternalConversationSettingsFragment : DSLSettingsFragment(
liveRecipient.observeForever(this) liveRecipient.observeForever(this)
SignalExecutors.BOUNDED.execute { SignalExecutors.BOUNDED.execute {
val threadId: Long? = DatabaseFactory.getThreadDatabase(ApplicationDependencies.getApplication()).getThreadIdFor(recipientId) val context: Context = ApplicationDependencies.getApplication()
store.update { state -> state.copy(threadId = threadId) } val threadId: Long? = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipientId)
val groupId: GroupId? = DatabaseFactory.getGroupDatabase(context).getGroup(recipientId).transform { it.id }.orNull()
store.update { state -> state.copy(threadId = threadId, groupId = groupId) }
} }
} }
override fun onRecipientChanged(recipient: Recipient) { override fun onRecipientChanged(recipient: Recipient) {
SignalExecutors.BOUNDED.execute { store.update { state -> state.copy(recipient = recipient) }
val threadId: Long? = DatabaseFactory.getThreadDatabase(ApplicationDependencies.getApplication()).getThreadIdFor(recipient.id)
store.update { InternalState(recipient, threadId) }
}
} }
override fun onCleared() { override fun onCleared() {
@ -205,6 +229,7 @@ class InternalConversationSettingsFragment : DSLSettingsFragment(
data class InternalState( data class InternalState(
val recipient: Recipient, val recipient: Recipient,
val threadId: Long? val threadId: Long?,
val groupId: GroupId?
) )
} }