mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-25 01:07:47 +00:00
Fix loading state in New Message Fragment
This commit is contained in:
parent
60d41ad10d
commit
f8e3bc7d9a
@ -183,6 +183,7 @@ fun EnterAccountId(
|
|||||||
.padding(horizontal = LocalDimensions.current.marginLarge)
|
.padding(horizontal = LocalDimensions.current.marginLarge)
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.contentDescription(R.string.next),
|
.contentDescription(R.string.next),
|
||||||
|
enabled = state.isNextButtonEnabled,
|
||||||
onClick = { callbacks.onContinue() }
|
onClick = { callbacks.onContinue() }
|
||||||
) {
|
) {
|
||||||
LoadingArcOr(state.loading) {
|
LoadingArcOr(state.loading) {
|
||||||
|
@ -4,27 +4,29 @@ import android.app.Application
|
|||||||
import androidx.lifecycle.AndroidViewModel
|
import androidx.lifecycle.AndroidViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.channels.Channel
|
import kotlinx.coroutines.channels.Channel
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.receiveAsFlow
|
import kotlinx.coroutines.flow.receiveAsFlow
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
|
import kotlinx.coroutines.isActive
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withTimeout
|
||||||
import network.loki.messenger.R
|
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.libsession.snode.SnodeAPI
|
||||||
import org.session.libsignal.utilities.PublicKeyValidation
|
import org.session.libsignal.utilities.PublicKeyValidation
|
||||||
import org.thoughtcrime.securesms.ui.GetString
|
import org.thoughtcrime.securesms.ui.GetString
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class NewMessageViewModel @Inject constructor(
|
class NewMessageViewModel @Inject constructor(
|
||||||
private val application: Application
|
private val application: Application
|
||||||
): AndroidViewModel(application), Callbacks {
|
): AndroidViewModel(application), Callbacks {
|
||||||
|
|
||||||
|
|
||||||
private val _state = MutableStateFlow(State())
|
private val _state = MutableStateFlow(State())
|
||||||
val state = _state.asStateFlow()
|
val state = _state.asStateFlow()
|
||||||
|
|
||||||
@ -34,11 +36,13 @@ class NewMessageViewModel @Inject constructor(
|
|||||||
private val _qrErrors = Channel<String>()
|
private val _qrErrors = Channel<String>()
|
||||||
val qrErrors: Flow<String> = _qrErrors.receiveAsFlow()
|
val qrErrors: Flow<String> = _qrErrors.receiveAsFlow()
|
||||||
|
|
||||||
|
private var job: Job? = null
|
||||||
|
|
||||||
override fun onChange(value: String) {
|
override fun onChange(value: String) {
|
||||||
_state.update { it.copy(
|
job?.cancel()
|
||||||
newMessageIdOrOns = value,
|
job = null
|
||||||
error = null
|
|
||||||
) }
|
_state.update { State(newMessageIdOrOns = value) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onContinue() {
|
override fun onContinue() {
|
||||||
@ -54,6 +58,8 @@ class NewMessageViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createPrivateChatIfPossible(onsNameOrPublicKey: String) {
|
private fun createPrivateChatIfPossible(onsNameOrPublicKey: String) {
|
||||||
|
if (job?.isActive == true) return
|
||||||
|
|
||||||
if (PublicKeyValidation.isValid(onsNameOrPublicKey, isPrefixRequired = false)) {
|
if (PublicKeyValidation.isValid(onsNameOrPublicKey, isPrefixRequired = false)) {
|
||||||
if (PublicKeyValidation.hasValidPrefix(onsNameOrPublicKey)) {
|
if (PublicKeyValidation.hasValidPrefix(onsNameOrPublicKey)) {
|
||||||
onPublicKey(onsNameOrPublicKey)
|
onPublicKey(onsNameOrPublicKey)
|
||||||
@ -64,11 +70,18 @@ class NewMessageViewModel @Inject constructor(
|
|||||||
// This could be an ONS name
|
// This could be an ONS name
|
||||||
_state.update { it.copy(error = null, loading = true) }
|
_state.update { it.copy(error = null, loading = true) }
|
||||||
|
|
||||||
SnodeAPI.getSessionID(onsNameOrPublicKey).successUi { hexEncodedPublicKey ->
|
job = viewModelScope.launch(Dispatchers.IO) {
|
||||||
_state.update { it.copy(loading = false) }
|
try {
|
||||||
onPublicKey(onsNameOrPublicKey)
|
withTimeout(5.seconds) {
|
||||||
}.failUi { exception ->
|
SnodeAPI.getSessionID(onsNameOrPublicKey).get()
|
||||||
_state.update { it.copy(loading = false, error = GetString(exception) { it.toMessage() }) }
|
}
|
||||||
|
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 newMessageIdOrOns: String = "",
|
||||||
val error: GetString? = null,
|
val error: GetString? = null,
|
||||||
val loading: Boolean = false
|
val loading: Boolean = false
|
||||||
)
|
) {
|
||||||
|
val isNextButtonEnabled: Boolean get() = newMessageIdOrOns.isNotBlank()
|
||||||
|
}
|
||||||
|
|
||||||
sealed interface Event {
|
sealed interface Event {
|
||||||
data class Success(val key: String): Event
|
data class Success(val key: String): Event
|
||||||
|
@ -93,12 +93,14 @@ fun OutlineButton(
|
|||||||
@Composable
|
@Composable
|
||||||
fun OutlineButton(
|
fun OutlineButton(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
enabled: Boolean = true,
|
||||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
content: @Composable () -> Unit = {}
|
content: @Composable () -> Unit = {}
|
||||||
) {
|
) {
|
||||||
OutlinedButton(
|
OutlinedButton(
|
||||||
modifier = modifier.applyButtonSize(),
|
modifier = modifier.applyButtonSize(),
|
||||||
|
enabled = enabled,
|
||||||
interactionSource = interactionSource,
|
interactionSource = interactionSource,
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
border = BorderStroke(1.dp, LocalButtonColor.current),
|
border = BorderStroke(1.dp, LocalButtonColor.current),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user