Fix loading state in New Message Fragment

pr/1451-theming
Andrew 11 months ago
parent 60d41ad10d
commit f8e3bc7d9a

@ -183,6 +183,7 @@ fun EnterAccountId(
.padding(horizontal = LocalDimensions.current.marginLarge)
.fillMaxWidth()
.contentDescription(R.string.next),
enabled = state.isNextButtonEnabled,
onClick = { callbacks.onContinue() }
) {
LoadingArcOr(state.loading) {

@ -4,27 +4,29 @@ import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.withTimeout
import network.loki.messenger.R
import nl.komponents.kovenant.ui.failUi
import nl.komponents.kovenant.ui.successUi
import org.session.libsession.snode.SnodeAPI
import org.session.libsignal.utilities.PublicKeyValidation
import org.thoughtcrime.securesms.ui.GetString
import javax.inject.Inject
import kotlin.time.Duration.Companion.seconds
@HiltViewModel
class NewMessageViewModel @Inject constructor(
private val application: Application
): AndroidViewModel(application), Callbacks {
private val _state = MutableStateFlow(State())
val state = _state.asStateFlow()
@ -34,11 +36,13 @@ class NewMessageViewModel @Inject constructor(
private val _qrErrors = Channel<String>()
val qrErrors: Flow<String> = _qrErrors.receiveAsFlow()
private var job: Job? = null
override fun onChange(value: String) {
_state.update { it.copy(
newMessageIdOrOns = value,
error = null
) }
job?.cancel()
job = null
_state.update { State(newMessageIdOrOns = value) }
}
override fun onContinue() {
@ -54,6 +58,8 @@ class NewMessageViewModel @Inject constructor(
}
private fun createPrivateChatIfPossible(onsNameOrPublicKey: String) {
if (job?.isActive == true) return
if (PublicKeyValidation.isValid(onsNameOrPublicKey, isPrefixRequired = false)) {
if (PublicKeyValidation.hasValidPrefix(onsNameOrPublicKey)) {
onPublicKey(onsNameOrPublicKey)
@ -64,11 +70,18 @@ class NewMessageViewModel @Inject constructor(
// This could be an ONS name
_state.update { it.copy(error = null, loading = true) }
SnodeAPI.getSessionID(onsNameOrPublicKey).successUi { hexEncodedPublicKey ->
_state.update { it.copy(loading = false) }
onPublicKey(onsNameOrPublicKey)
}.failUi { exception ->
_state.update { it.copy(loading = false, error = GetString(exception) { it.toMessage() }) }
job = viewModelScope.launch(Dispatchers.IO) {
try {
withTimeout(5.seconds) {
SnodeAPI.getSessionID(onsNameOrPublicKey).get()
}
if (isActive) {
_state.update { it.copy(loading = false) }
onPublicKey(onsNameOrPublicKey)
}
} catch (e: Exception) {
if (isActive) _state.update { it.copy(loading = false, error = GetString(e) { it.toMessage() }) }
}
}
}
}
@ -87,7 +100,9 @@ data class State(
val newMessageIdOrOns: String = "",
val error: GetString? = null,
val loading: Boolean = false
)
) {
val isNextButtonEnabled: Boolean get() = newMessageIdOrOns.isNotBlank()
}
sealed interface Event {
data class Success(val key: String): Event

@ -93,12 +93,14 @@ fun OutlineButton(
@Composable
fun OutlineButton(
modifier: Modifier = Modifier,
enabled: Boolean = true,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
onClick: () -> Unit,
content: @Composable () -> Unit = {}
) {
OutlinedButton(
modifier = modifier.applyButtonSize(),
enabled = enabled,
interactionSource = interactionSource,
onClick = onClick,
border = BorderStroke(1.dp, LocalButtonColor.current),

Loading…
Cancel
Save