mirror of
https://github.com/oxen-io/session-android.git
synced 2025-04-04 00:45:38 +00:00
Add group disappearing messages settings footer
This commit is contained in:
parent
68ca048267
commit
da8d93504a
@ -5,6 +5,7 @@ import android.os.Parcelable
|
|||||||
import android.util.SparseArray
|
import android.util.SparseArray
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.core.text.HtmlCompat
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.recyclerview.widget.DividerItemDecoration
|
import androidx.recyclerview.widget.DividerItemDecoration
|
||||||
@ -35,16 +36,12 @@ class ExpirationSettingsActivity: PassphraseRequiredActionBarActivity() {
|
|||||||
intent.getLongExtra(THREAD_ID, -1)
|
intent.getLongExtra(THREAD_ID, -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val expirationType: ExpirationType? by lazy {
|
|
||||||
ExpirationType.valueOf(intent.getIntExtra(EXPIRATION_TYPE, -1))
|
|
||||||
}
|
|
||||||
|
|
||||||
private val viewModel: ExpirationSettingsViewModel by viewModels {
|
private val viewModel: ExpirationSettingsViewModel by viewModels {
|
||||||
val afterReadOptions = resources.getIntArray(R.array.read_expiration_time_values).map(Int::toString)
|
val afterReadOptions = resources.getIntArray(R.array.read_expiration_time_values).map(Int::toString)
|
||||||
.zip(resources.getStringArray(R.array.read_expiration_time_names)) { value, name -> RadioOption(value, name)}
|
.zip(resources.getStringArray(R.array.read_expiration_time_names)) { value, name -> RadioOption(value, name)}
|
||||||
val afterSendOptions = resources.getIntArray(R.array.send_expiration_time_values).map(Int::toString)
|
val afterSendOptions = resources.getIntArray(R.array.send_expiration_time_values).map(Int::toString)
|
||||||
.zip(resources.getStringArray(R.array.send_expiration_time_names)) { value, name -> RadioOption(value, name)}
|
.zip(resources.getStringArray(R.array.send_expiration_time_names)) { value, name -> RadioOption(value, name)}
|
||||||
viewModelFactory.create(threadId, expirationType, afterReadOptions, afterSendOptions)
|
viewModelFactory.create(threadId, afterReadOptions, afterSendOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSaveInstanceState(outState: Bundle) {
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
@ -84,8 +81,6 @@ class ExpirationSettingsActivity: PassphraseRequiredActionBarActivity() {
|
|||||||
val deleteTypeOptionAdapter = RadioOptionAdapter {
|
val deleteTypeOptionAdapter = RadioOptionAdapter {
|
||||||
viewModel.onExpirationTypeSelected(it)
|
viewModel.onExpirationTypeSelected(it)
|
||||||
}
|
}
|
||||||
binding.textViewDeleteType.isVisible = expirationType == null
|
|
||||||
binding.layoutDeleteTypes.isVisible = expirationType == null
|
|
||||||
binding.recyclerViewDeleteTypes.apply {
|
binding.recyclerViewDeleteTypes.apply {
|
||||||
adapter = deleteTypeOptionAdapter
|
adapter = deleteTypeOptionAdapter
|
||||||
addItemDecoration(ContextCompat.getDrawable(this@ExpirationSettingsActivity, R.drawable.conversation_menu_divider)!!.let {
|
addItemDecoration(ContextCompat.getDrawable(this@ExpirationSettingsActivity, R.drawable.conversation_menu_divider)!!.let {
|
||||||
@ -117,11 +112,19 @@ class ExpirationSettingsActivity: PassphraseRequiredActionBarActivity() {
|
|||||||
}
|
}
|
||||||
launch {
|
launch {
|
||||||
viewModel.expirationTimerOptions.collect { options ->
|
viewModel.expirationTimerOptions.collect { options ->
|
||||||
binding.textViewTimer.isVisible = options.isNotEmpty() && expirationType == null
|
binding.textViewTimer.isVisible = options.isNotEmpty() && viewModel.showExpirationTypeSelector
|
||||||
binding.layoutTimer.isVisible = options.isNotEmpty()
|
binding.layoutTimer.isVisible = options.isNotEmpty()
|
||||||
timerOptionAdapter.submitList(options)
|
timerOptionAdapter.submitList(options)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
launch {
|
||||||
|
viewModel.recipient.collect {
|
||||||
|
binding.textViewDeleteType.isVisible = viewModel.showExpirationTypeSelector
|
||||||
|
binding.layoutDeleteTypes.isVisible = viewModel.showExpirationTypeSelector
|
||||||
|
binding.textViewFooter.isVisible = it?.isClosedGroupRecipient == true
|
||||||
|
binding.textViewFooter.text = HtmlCompat.fromHtml(getString(R.string.activity_expiration_settings_group_footer), HtmlCompat.FROM_HTML_MODE_COMPACT)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -130,7 +133,7 @@ class ExpirationSettingsActivity: PassphraseRequiredActionBarActivity() {
|
|||||||
setSupportActionBar(binding.toolbar)
|
setSupportActionBar(binding.toolbar)
|
||||||
val actionBar = supportActionBar ?: return
|
val actionBar = supportActionBar ?: return
|
||||||
actionBar.title = getString(R.string.activity_expiration_settings_title)
|
actionBar.title = getString(R.string.activity_expiration_settings_title)
|
||||||
actionBar.subtitle = if (expirationType == ExpirationType.DELETE_AFTER_SEND) {
|
actionBar.subtitle = if (viewModel.selectedExpirationType.value == ExpirationType.DELETE_AFTER_SEND) {
|
||||||
getString(R.string.activity_expiration_settings_subtitle_sent)
|
getString(R.string.activity_expiration_settings_subtitle_sent)
|
||||||
} else {
|
} else {
|
||||||
getString(R.string.activity_expiration_settings_subtitle)
|
getString(R.string.activity_expiration_settings_subtitle)
|
||||||
@ -142,8 +145,6 @@ class ExpirationSettingsActivity: PassphraseRequiredActionBarActivity() {
|
|||||||
companion object {
|
companion object {
|
||||||
private const val SCROLL_PARCEL = "scroll_parcel"
|
private const val SCROLL_PARCEL = "scroll_parcel"
|
||||||
const val THREAD_ID = "thread_id"
|
const val THREAD_ID = "thread_id"
|
||||||
const val EXPIRATION_TYPE = "expiration_type"
|
|
||||||
const val READ_ONLY = "read_only"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -10,6 +10,7 @@ import kotlinx.coroutines.flow.StateFlow
|
|||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.mapLatest
|
import kotlinx.coroutines.flow.mapLatest
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import org.session.libsession.utilities.recipients.Recipient
|
import org.session.libsession.utilities.recipients.Recipient
|
||||||
import org.session.libsignal.protos.SignalServiceProtos.Content.ExpirationType
|
import org.session.libsignal.protos.SignalServiceProtos.Content.ExpirationType
|
||||||
import org.thoughtcrime.securesms.database.ThreadDatabase
|
import org.thoughtcrime.securesms.database.ThreadDatabase
|
||||||
@ -17,22 +18,32 @@ import org.thoughtcrime.securesms.preferences.RadioOption
|
|||||||
|
|
||||||
class ExpirationSettingsViewModel(
|
class ExpirationSettingsViewModel(
|
||||||
private val threadId: Long,
|
private val threadId: Long,
|
||||||
private val expirationType: ExpirationType?,
|
|
||||||
private val afterReadOptions: List<RadioOption>,
|
private val afterReadOptions: List<RadioOption>,
|
||||||
private val afterSendOptions: List<RadioOption>,
|
private val afterSendOptions: List<RadioOption>,
|
||||||
private val threadDb: ThreadDatabase
|
private val threadDb: ThreadDatabase
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
val recipient: Recipient?
|
var showExpirationTypeSelector: Boolean = false
|
||||||
get() = threadDb.getRecipientForThreadId(threadId)
|
private set
|
||||||
|
|
||||||
private val _selectedExpirationType = MutableStateFlow(expirationType)
|
private val _recipient = MutableStateFlow<Recipient?>(null)
|
||||||
|
val recipient: StateFlow<Recipient?> = _recipient
|
||||||
|
|
||||||
|
private val _selectedExpirationType = MutableStateFlow<ExpirationType?>(null)
|
||||||
val selectedExpirationType: StateFlow<ExpirationType?> = _selectedExpirationType
|
val selectedExpirationType: StateFlow<ExpirationType?> = _selectedExpirationType
|
||||||
|
|
||||||
private val _expirationTimerOptions = MutableStateFlow<List<RadioOption>>(emptyList())
|
private val _expirationTimerOptions = MutableStateFlow<List<RadioOption>>(emptyList())
|
||||||
val expirationTimerOptions: StateFlow<List<RadioOption>> = _expirationTimerOptions
|
val expirationTimerOptions: StateFlow<List<RadioOption>> = _expirationTimerOptions
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
viewModelScope.launch {
|
||||||
|
val recipient = threadDb.getRecipientForThreadId(threadId)
|
||||||
|
_recipient.value = recipient
|
||||||
|
showExpirationTypeSelector = recipient?.isContactRecipient == true && recipient.isLocalNumber == false
|
||||||
|
}
|
||||||
|
if (recipient.value?.isLocalNumber == true || recipient.value?.isClosedGroupRecipient == true) {
|
||||||
|
_selectedExpirationType.value = ExpirationType.DELETE_AFTER_SEND
|
||||||
|
}
|
||||||
selectedExpirationType.mapLatest {
|
selectedExpirationType.mapLatest {
|
||||||
when (it) {
|
when (it) {
|
||||||
ExpirationType.DELETE_AFTER_SEND -> afterSendOptions
|
ExpirationType.DELETE_AFTER_SEND -> afterSendOptions
|
||||||
@ -56,7 +67,6 @@ class ExpirationSettingsViewModel(
|
|||||||
interface AssistedFactory {
|
interface AssistedFactory {
|
||||||
fun create(
|
fun create(
|
||||||
threadId: Long,
|
threadId: Long,
|
||||||
expirationType: ExpirationType?,
|
|
||||||
@Assisted("afterRead") afterReadOptions: List<RadioOption>,
|
@Assisted("afterRead") afterReadOptions: List<RadioOption>,
|
||||||
@Assisted("afterSend") afterSendOptions: List<RadioOption>
|
@Assisted("afterSend") afterSendOptions: List<RadioOption>
|
||||||
): Factory
|
): Factory
|
||||||
@ -65,7 +75,6 @@ class ExpirationSettingsViewModel(
|
|||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
class Factory @AssistedInject constructor(
|
class Factory @AssistedInject constructor(
|
||||||
@Assisted private val threadId: Long,
|
@Assisted private val threadId: Long,
|
||||||
@Assisted private val expirationType: ExpirationType?,
|
|
||||||
@Assisted("afterRead") private val afterReadOptions: List<RadioOption>,
|
@Assisted("afterRead") private val afterReadOptions: List<RadioOption>,
|
||||||
@Assisted("afterSend") private val afterSendOptions: List<RadioOption>,
|
@Assisted("afterSend") private val afterSendOptions: List<RadioOption>,
|
||||||
private val threadDb: ThreadDatabase
|
private val threadDb: ThreadDatabase
|
||||||
@ -74,7 +83,6 @@ class ExpirationSettingsViewModel(
|
|||||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||||
return ExpirationSettingsViewModel(
|
return ExpirationSettingsViewModel(
|
||||||
threadId,
|
threadId,
|
||||||
expirationType,
|
|
||||||
afterReadOptions,
|
afterReadOptions,
|
||||||
afterSendOptions,
|
afterSendOptions,
|
||||||
threadDb
|
threadDb
|
||||||
|
@ -991,9 +991,6 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
|||||||
}
|
}
|
||||||
val expirationIntent = Intent(this, ExpirationSettingsActivity::class.java)
|
val expirationIntent = Intent(this, ExpirationSettingsActivity::class.java)
|
||||||
expirationIntent.putExtra(ExpirationSettingsActivity.THREAD_ID, viewModel.threadId)
|
expirationIntent.putExtra(ExpirationSettingsActivity.THREAD_ID, viewModel.threadId)
|
||||||
if (thread.isLocalNumber || thread.isClosedGroupRecipient) {
|
|
||||||
expirationIntent.putExtra(ExpirationSettingsActivity.EXPIRATION_TYPE, ExpirationType.DELETE_AFTER_SEND_VALUE)
|
|
||||||
}
|
|
||||||
show(expirationIntent, true)
|
show(expirationIntent, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +72,6 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginHorizontal="@dimen/small_spacing"
|
android:layout_marginHorizontal="@dimen/small_spacing"
|
||||||
android:layout_marginBottom="@dimen/massive_spacing"
|
|
||||||
android:background="@drawable/preference_single"
|
android:background="@drawable/preference_single"
|
||||||
android:paddingHorizontal="@dimen/large_spacing"
|
android:paddingHorizontal="@dimen/large_spacing"
|
||||||
android:paddingVertical="@dimen/medium_spacing">
|
android:paddingVertical="@dimen/medium_spacing">
|
||||||
@ -87,6 +86,20 @@
|
|||||||
tools:listitem="@layout/item_selectable" />
|
tools:listitem="@layout/item_selectable" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_view_footer"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="@dimen/massive_spacing"
|
||||||
|
android:paddingHorizontal="@dimen/very_large_spacing"
|
||||||
|
android:paddingVertical="@dimen/small_spacing"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:text="@string/activity_expiration_settings_group_footer"
|
||||||
|
android:textColor="?android:textColorTertiary"
|
||||||
|
android:textSize="@dimen/very_small_font_size"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
@ -881,4 +881,5 @@
|
|||||||
<string name="expiration_settings_set_button_title">Set</string>
|
<string name="expiration_settings_set_button_title">Set</string>
|
||||||
<string name="activity_expiration_settings_delete_type">Delete Type</string>
|
<string name="activity_expiration_settings_delete_type">Delete Type</string>
|
||||||
<string name="activity_expiration_settings_timer">Timer</string>
|
<string name="activity_expiration_settings_timer">Timer</string>
|
||||||
|
<string name="activity_expiration_settings_group_footer"><![CDATA[This setting applies to everyone in this conversation.<br/>Only group admins can change this setting.]]></string>
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user