|
|
|
@ -1,6 +1,7 @@
|
|
|
|
|
package org.thoughtcrime.securesms.onboarding
|
|
|
|
|
|
|
|
|
|
import android.app.Application
|
|
|
|
|
import androidx.compose.runtime.snapshots.SnapshotApplyResult
|
|
|
|
|
import androidx.lifecycle.AndroidViewModel
|
|
|
|
|
import androidx.lifecycle.viewModelScope
|
|
|
|
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
|
|
|
@ -8,7 +9,14 @@ import kotlinx.coroutines.Dispatchers
|
|
|
|
|
import kotlinx.coroutines.channels.Channel
|
|
|
|
|
import kotlinx.coroutines.flow.MutableStateFlow
|
|
|
|
|
import kotlinx.coroutines.flow.asStateFlow
|
|
|
|
|
import kotlinx.coroutines.flow.collect
|
|
|
|
|
import kotlinx.coroutines.flow.consumeAsFlow
|
|
|
|
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
|
|
|
|
import kotlinx.coroutines.flow.first
|
|
|
|
|
import kotlinx.coroutines.flow.map
|
|
|
|
|
import kotlinx.coroutines.flow.receiveAsFlow
|
|
|
|
|
import kotlinx.coroutines.flow.takeWhile
|
|
|
|
|
import kotlinx.coroutines.flow.transformWhile
|
|
|
|
|
import kotlinx.coroutines.flow.update
|
|
|
|
|
import kotlinx.coroutines.launch
|
|
|
|
|
import org.session.libsignal.crypto.MnemonicCodec
|
|
|
|
@ -25,62 +33,39 @@ class LinkDeviceViewModel @Inject constructor(
|
|
|
|
|
private val state = MutableStateFlow(LinkDeviceState())
|
|
|
|
|
val stateFlow = state.asStateFlow()
|
|
|
|
|
|
|
|
|
|
private val qrErrors = Channel<Throwable>()
|
|
|
|
|
private val event = Channel<LinkDeviceEvent>()
|
|
|
|
|
val eventFlow = event.receiveAsFlow()
|
|
|
|
|
|
|
|
|
|
fun onRecoveryPhrase() {
|
|
|
|
|
val mnemonic = state.value.recoveryPhrase
|
|
|
|
|
tryPhrase(mnemonic)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fun onQrPhrase(string: String) {
|
|
|
|
|
tryPhrase(string)
|
|
|
|
|
}
|
|
|
|
|
private val phrases = Channel<String>()
|
|
|
|
|
|
|
|
|
|
private fun tryPhrase(mnemonic: String) {
|
|
|
|
|
viewModelScope.launch(Dispatchers.IO) {
|
|
|
|
|
try {
|
|
|
|
|
MnemonicCodec { MnemonicUtilities.loadFileContents(getApplication(), it) }
|
|
|
|
|
.decode(mnemonic)
|
|
|
|
|
.let(Hex::fromStringCondensed)
|
|
|
|
|
.let(::LinkDeviceEvent)
|
|
|
|
|
.let { event.send(it) }
|
|
|
|
|
} catch (exception: Exception) {
|
|
|
|
|
state.update {
|
|
|
|
|
it.copy(
|
|
|
|
|
error = when (exception) {
|
|
|
|
|
is MnemonicCodec.DecodingError -> exception.description
|
|
|
|
|
else -> "An error occurred."
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
init {
|
|
|
|
|
viewModelScope.launch {
|
|
|
|
|
phrases.receiveAsFlow().map {
|
|
|
|
|
runCatching {
|
|
|
|
|
MnemonicCodec { MnemonicUtilities.loadFileContents(getApplication(), it) }
|
|
|
|
|
.decode(it)
|
|
|
|
|
.let(Hex::fromStringCondensed)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}.takeWhile {
|
|
|
|
|
it.getOrNull()?.let(::LinkDeviceEvent)?.let { event.send(it) }
|
|
|
|
|
it.exceptionOrNull()?.let { qrErrors.send(it) }
|
|
|
|
|
it.isFailure
|
|
|
|
|
}.collect()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// override fun handleQRCodeScanned(mnemonic: String) {
|
|
|
|
|
// try {
|
|
|
|
|
// val seed = Hex.fromStringCondensed(mnemonic)
|
|
|
|
|
// continueWithSeed(seed)
|
|
|
|
|
// } catch (e: Exception) {
|
|
|
|
|
// Log.e("Loki","Error getting seed from QR code", e)
|
|
|
|
|
// Toast.makeText(this, "An error occurred.", Toast.LENGTH_LONG).show()
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
fun onRecoveryPhrase() {
|
|
|
|
|
viewModelScope.launch {
|
|
|
|
|
phrases.send(state.value.recoveryPhrase)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// fun continueWithMnemonic(mnemonic: String) {
|
|
|
|
|
// val loadFileContents: (String) -> String = { fileName ->
|
|
|
|
|
// MnemonicUtilities.loadFileContents(this, fileName)
|
|
|
|
|
// }
|
|
|
|
|
// try {
|
|
|
|
|
// val hexEncodedSeed = MnemonicCodec(loadFileContents).decode(mnemonic)
|
|
|
|
|
// val seed = Hex.fromStringCondensed(hexEncodedSeed)
|
|
|
|
|
// continueWithSeed(seed)
|
|
|
|
|
// } catch (error: Exception) {
|
|
|
|
|
// val message = if (error is MnemonicCodec.DecodingError) {
|
|
|
|
|
// error.description
|
|
|
|
|
// } else {
|
|
|
|
|
// "An error occurred."
|
|
|
|
|
fun onQrPhrase(string: String) {
|
|
|
|
|
viewModelScope.launch {
|
|
|
|
|
phrases.send(string)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fun onChange(recoveryPhrase: String) {
|
|
|
|
|
state.value = LinkDeviceState(recoveryPhrase)
|
|
|
|
|