Reinstate group footer

This commit is contained in:
andrew 2023-08-27 18:44:29 +09:30
parent 97f28fd2e5
commit b65a383ac5
3 changed files with 62 additions and 79 deletions

View File

@ -16,6 +16,7 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.itemsIndexed
@ -41,10 +42,18 @@ import androidx.compose.ui.graphics.CompositingStrategy
import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.layout.ModifierLocalBeyondBoundsLayout import androidx.compose.ui.layout.ModifierLocalBeyondBoundsLayout
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.text.HtmlCompat
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle import androidx.lifecycle.repeatOnLifecycle
@ -82,14 +91,6 @@ class ExpirationSettingsActivity: PassphraseRequiredActionBarActivity() {
viewModelFactory.create(threadId) viewModelFactory.create(threadId)
} }
// override fun onSaveInstanceState(outState: Bundle) {
// super.onSaveInstanceState(outState)
// val scrollParcelArray = SparseArray<Parcelable>()
// binding.scrollView.saveHierarchyState(scrollParcelArray)
// outState.putSparseParcelableArray(SCROLL_PARCEL, scrollParcelArray)
// }
override fun onCreate(savedInstanceState: Bundle?, ready: Boolean) { override fun onCreate(savedInstanceState: Bundle?, ready: Boolean) {
super.onCreate(savedInstanceState, ready) super.onCreate(savedInstanceState, ready)
binding = ActivityExpirationSettingsBinding.inflate(layoutInflater) binding = ActivityExpirationSettingsBinding.inflate(layoutInflater)
@ -99,31 +100,10 @@ class ExpirationSettingsActivity: PassphraseRequiredActionBarActivity() {
binding.container.setContent { DisappearingMessagesScreen() } binding.container.setContent { DisappearingMessagesScreen() }
// savedInstanceState?.let { bundle ->
// val scrollStateParcel = bundle.getSparseParcelableArray<Parcelable>(SCROLL_PARCEL)
// if (scrollStateParcel != null) {
// binding.scrollView.restoreHierarchyState(scrollStateParcel)
// }
// }
// val deleteTypeOptions = viewModel.getDeleteOptions()
// binding.buttonSet.setOnClickListener {
// viewModel.onSetClick()
// }
lifecycleScope.launch { lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) { repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.state.collect { state -> viewModel.state.collect { state ->
// actionBar?.subtitle = if (state.selectedExpirationType.value is ExpiryMode.AfterSend) { actionBar?.subtitle = state.subtitle(this@ExpirationSettingsActivity)
// getString(R.string.activity_expiration_settings_subtitle_sent)
// } else {
// getString(R.string.activity_expiration_settings_subtitle)
// }
// binding.textViewDeleteType.isVisible = state.showExpirationTypeSelector
// binding.layoutDeleteTypes.isVisible = state.showExpirationTypeSelector
// binding.textViewFooter.isVisible = state.recipient?.isClosedGroupRecipient == true
// binding.textViewFooter.text = HtmlCompat.fromHtml(getString(R.string.activity_expiration_settings_group_footer), HtmlCompat.FROM_HTML_MODE_COMPACT)
when (state.settingsSaved) { when (state.settingsSaved) {
true -> { true -> {
@ -181,7 +161,6 @@ class ExpirationSettingsActivity: PassphraseRequiredActionBarActivity() {
} }
companion object { companion object {
private const val SCROLL_PARCEL = "scroll_parcel"
const val THREAD_ID = "thread_id" const val THREAD_ID = "thread_id"
} }
@ -215,6 +194,14 @@ fun DisappearingMessages(
state.cards.filter { it.options.isNotEmpty() }.forEach { state.cards.filter { it.options.isNotEmpty() }.forEach {
OptionsCard(it) OptionsCard(it)
} }
if (state.showGroupFooter) Text(text = stringResource(R.string.activity_expiration_settings_group_footer),
style = TextStyle(
fontSize = 11.sp,
fontWeight = FontWeight(400),
color = Color(0xFFA1A2A1),
textAlign = TextAlign.Center),
modifier = Modifier.fillMaxWidth())
} }
} }
@ -253,7 +240,8 @@ fun Modifier.fadingEdges(
val bottomColors = listOf(Color.Black, Color.Transparent) val bottomColors = listOf(Color.Black, Color.Transparent)
val bottomEndY = size.height - scrollState.maxValue + scrollState.value val bottomEndY = size.height - scrollState.maxValue + scrollState.value
val bottomGradientHeight = min(bottomEdgeHeight.toPx(), scrollState.maxValue.toFloat() - scrollState.value) val bottomGradientHeight =
min(bottomEdgeHeight.toPx(), scrollState.maxValue.toFloat() - scrollState.value)
if (bottomGradientHeight != 0f) drawRect( if (bottomGradientHeight != 0f) drawRect(
brush = Brush.verticalGradient( brush = Brush.verticalGradient(
colors = bottomColors, colors = bottomColors,
@ -280,22 +268,6 @@ fun OptionsCard(card: CardModel) {
} }
} }
@Composable
fun Gradient(height: Dp, modifier: Modifier = Modifier) {
Box(
modifier = modifier
.fillMaxWidth()
.height(height)
// .background(
// brush = Brush.verticalGradient(
// colors = listOf(Color.Transparent, MaterialTheme.colors.primary),
// startY = 0f,
// endY = height.value
// )
// )
)
}
@Composable @Composable
fun TitledRadioButton(option: OptionModel) { fun TitledRadioButton(option: OptionModel) {
Row(modifier = Modifier Row(modifier = Modifier
@ -341,8 +313,8 @@ fun PreviewMessageDetails(
DisappearingMessages( DisappearingMessages(
UiState( UiState(
cards = listOf( cards = listOf(
CardModel(GetString(R.string.activity_expiration_settings_delete_type), typeOptions()), CardModel(GetString(R.string.activity_expiration_settings_delete_type), previewTypeOptions()),
CardModel(GetString(R.string.activity_expiration_settings_timer), timeOptions()) CardModel(GetString(R.string.activity_expiration_settings_timer), previewTimeOptions())
) )
), ),
modifier = Modifier.size(400.dp, 600.dp) modifier = Modifier.size(400.dp, 600.dp)
@ -350,14 +322,14 @@ fun PreviewMessageDetails(
} }
} }
fun typeOptions() = listOf( fun previewTypeOptions() = listOf(
OptionModel(GetString(R.string.expiration_off)), OptionModel(GetString(R.string.expiration_off)),
OptionModel(GetString(R.string.expiration_type_disappear_legacy)), OptionModel(GetString(R.string.expiration_type_disappear_legacy)),
OptionModel(GetString(R.string.expiration_type_disappear_after_read)), OptionModel(GetString(R.string.expiration_type_disappear_after_read)),
OptionModel(GetString(R.string.expiration_type_disappear_after_send)) OptionModel(GetString(R.string.expiration_type_disappear_after_send))
) )
fun timeOptions() = listOf( fun previewTimeOptions() = listOf(
OptionModel(GetString("1 Minute")), OptionModel(GetString("1 Minute")),
OptionModel(GetString("5 Minutes")), OptionModel(GetString("5 Minutes")),
OptionModel(GetString("1 Week")), OptionModel(GetString("1 Week")),

View File

@ -16,6 +16,9 @@ import network.loki.messenger.BuildConfig
import network.loki.messenger.R import network.loki.messenger.R
import network.loki.messenger.libsession_util.util.ExpiryMode import network.loki.messenger.libsession_util.util.ExpiryMode
import org.session.libsession.messaging.messages.ExpirationConfiguration import org.session.libsession.messaging.messages.ExpirationConfiguration
import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate
import org.session.libsession.messaging.sending_receiving.MessageSender
import org.session.libsession.snode.SnodeAPI
import org.session.libsession.utilities.ExpirationUtil import org.session.libsession.utilities.ExpirationUtil
import org.session.libsession.utilities.SSKEnvironment.MessageExpirationManagerProtocol import org.session.libsession.utilities.SSKEnvironment.MessageExpirationManagerProtocol
import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.TextSecurePreferences
@ -48,7 +51,8 @@ class ExpirationSettingsViewModel(
cards = listOf( cards = listOf(
CardModel(GetString(R.string.activity_expiration_settings_delete_type), typeOptions(it)), CardModel(GetString(R.string.activity_expiration_settings_delete_type), typeOptions(it)),
CardModel(GetString(R.string.activity_expiration_settings_timer), timeOptions(it)) CardModel(GetString(R.string.activity_expiration_settings_timer), timeOptions(it))
) ),
showGroupFooter = it.isGroup
) )
} }
@ -64,6 +68,7 @@ class ExpirationSettingsViewModel(
?.run { address.toGroupString().let(groupDb::getGroup).orNull() } ?.run { address.toGroupString().let(groupDb::getGroup).orNull() }
_state.update { state -> _state.update { state ->
state.copy( state.copy(
isGroup = groupInfo != null,
isSelfAdmin = groupInfo == null || groupInfo.admins.any{ it.serialize() == textSecurePreferences.getLocalNumber() }, isSelfAdmin = groupInfo == null || groupInfo.admins.any{ it.serialize() == textSecurePreferences.getLocalNumber() },
recipient = recipient, recipient = recipient,
expiryMode = expiryMode expiryMode = expiryMode
@ -159,32 +164,32 @@ class ExpirationSettingsViewModel(
fun onSetClick() = viewModelScope.launch { fun onSetClick() = viewModelScope.launch {
val state = _state.value val state = _state.value
// val expiryMode = _selectedExpirationTimer.value?.value ?: ExpiryMode.NONE val expiryMode = state.expiryMode ?: ExpiryMode.NONE
// val typeValue = expiryMode.let { val typeValue = expiryMode.let {
// if (it is ExpiryMode.Legacy) ExpiryMode.AfterRead(it.expirySeconds) if (it is ExpiryMode.Legacy) ExpiryMode.AfterRead(it.expirySeconds)
// else it else it
// } }
val address = state.recipient?.address val address = state.recipient?.address
// if (address == null || expirationConfig?.expiryMode == typeValue) { if (address == null || expirationConfig?.expiryMode == typeValue) {
// _state.update { _state.update {
// it.copy(settingsSaved = false) it.copy(settingsSaved = false)
// } }
// return@launch return@launch
// } }
// val expiryChangeTimestampMs = SnodeAPI.nowWithOffset val expiryChangeTimestampMs = SnodeAPI.nowWithOffset
// storage.setExpirationConfiguration(ExpirationConfiguration(threadId, typeValue, expiryChangeTimestampMs)) storage.setExpirationConfiguration(ExpirationConfiguration(threadId, typeValue, expiryChangeTimestampMs))
//
// val message = ExpirationTimerUpdate(typeValue.expirySeconds.toInt()) val message = ExpirationTimerUpdate(typeValue.expirySeconds.toInt())
// message.sender = textSecurePreferences.getLocalNumber() message.sender = textSecurePreferences.getLocalNumber()
// message.recipient = address.serialize() message.recipient = address.serialize()
// message.sentTimestamp = expiryChangeTimestampMs message.sentTimestamp = expiryChangeTimestampMs
// messageExpirationManager.setExpirationTimer(message, typeValue) messageExpirationManager.setExpirationTimer(message, typeValue)
//
// MessageSender.send(message, address) MessageSender.send(message, address)
// state.update { _state.update {
// it.copy(settingsSaved = true) it.copy(settingsSaved = true)
// } }
} }
@dagger.assisted.AssistedFactory @dagger.assisted.AssistedFactory
@ -214,19 +219,25 @@ class ExpirationSettingsViewModel(
} }
data class State( data class State(
val isGroup: Boolean = false,
val isSelfAdmin: Boolean = false, val isSelfAdmin: Boolean = false,
val settingsSaved: Boolean? = null, val settingsSaved: Boolean? = null,
val recipient: Recipient? = null, val recipient: Recipient? = null,
val expiryMode: ExpiryMode? = null, val expiryMode: ExpiryMode? = null,
val types: List<ExpiryType> = emptyList() val types: List<ExpiryType> = emptyList()
) { ) {
val subtitle get() = when (expiryType) {
ExpiryType.AFTER_SEND -> GetString(R.string.activity_expiration_settings_subtitle_sent)
else -> GetString(R.string.activity_expiration_settings_subtitle)
}
val duration get() = expiryMode?.duration val duration get() = expiryMode?.duration
val isSelf = recipient?.isLocalNumber == true val isSelf = recipient?.isLocalNumber == true
val expiryType get() = expiryMode?.type val expiryType get() = expiryMode?.type
} }
data class UiState( data class UiState(
val cards: List<CardModel> = emptyList() val cards: List<CardModel> = emptyList(),
val showGroupFooter: Boolean = false
) )
data class CardModel( data class CardModel(

View File

@ -1049,7 +1049,7 @@
<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> <string name="activity_expiration_settings_group_footer">This setting applies to everyone in this conversation.\nOnly group admins can change this setting.</string>
<string name="activity_conversation_outdated_client_banner_text">%s is using an outdated client. Disappearing messages may not work as expected.</string> <string name="activity_conversation_outdated_client_banner_text">%s is using an outdated client. Disappearing messages may not work as expected.</string>
<string name="ExpirationSettingsActivity_settings_updated">Settings updated</string> <string name="ExpirationSettingsActivity_settings_updated">Settings updated</string>
<string name="ExpirationSettingsActivity_settings_not_updated">Settings not updated and please try again</string> <string name="ExpirationSettingsActivity_settings_not_updated">Settings not updated and please try again</string>