Implement restore from seed UI

This commit is contained in:
Niels Andriesse 2019-07-17 10:26:06 +10:00
parent bac4b86ec3
commit 659d9e6a8f
4 changed files with 83 additions and 11 deletions

View File

@ -40,7 +40,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="32dp" android:layout_marginTop="32dp"
app:labeledEditText_background="@color/white" app:labeledEditText_background="@color/white"
app:labeledEditText_label="Display Name (Optional)"/> app:labeledEditText_label="@string/activity_account_details_name_edit_text_label"/>
<com.dd.CircularProgressButton <com.dd.CircularProgressButton
android:id="@+id/nextButton" android:id="@+id/nextButton"

View File

@ -14,7 +14,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="32dp" android:layout_marginStart="32dp"
android:layout_marginEnd="32dp" android:layout_marginEnd="32dp"
android:orientation="vertical"> android:orientation="vertical"
android:animateLayoutChanges="true">
<TextView <TextView
android:id="@+id/titleTextView" android:id="@+id/titleTextView"
@ -26,12 +27,12 @@
android:textAlignment="center" /> android:textAlignment="center" />
<TextView <TextView
android:id="@+id/subtitleTextView" android:id="@+id/seedExplanationTextView1"
style="@style/Signal.Text.Body" style="@style/Signal.Text.Body"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="16dp" android:layout_marginTop="24dp"
android:text="@string/activity_key_pair_subtitle" android:text="@string/activity_key_pair_seed_explanation_1"
android:textStyle="bold" android:textStyle="bold"
android:textAlignment="center" /> android:textAlignment="center" />
@ -57,8 +58,38 @@
android:elevation="0dp" android:elevation="0dp"
android:stateListAnimator="@null" /> android:stateListAnimator="@null" />
<TextView
android:id="@+id/seedExplanationTextView2"
style="@style/Signal.Text.Body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:visibility="gone"
android:text="@string/activity_key_pair_seed_explanation_2"
android:textAlignment="center" />
<org.thoughtcrime.securesms.components.LabeledEditText
android:id="@+id/mnemonicEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginBottom="20dp"
android:visibility="gone"
app:labeledEditText_background="@color/white"
app:labeledEditText_label="@string/activity_key_pair_mnemonic_edit_text_label"/>
<Button
android:id="@+id/toggleModeButton"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/white"
android:textColor="@color/signal_primary"
android:text="@string/activity_key_pair_toggle_mode_button_title_1"
android:elevation="0dp"
android:stateListAnimator="@null" />
<com.dd.CircularProgressButton <com.dd.CircularProgressButton
android:id="@+id/registerButton" android:id="@+id/registerOrRestoreButton"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="50dp" android:layout_height="50dp"
android:layout_marginTop="20dp" android:layout_marginTop="20dp"
@ -69,7 +100,7 @@
app:cpb_colorProgress="@color/textsecure_primary" app:cpb_colorProgress="@color/textsecure_primary"
app:cpb_cornerRadius="4dp" app:cpb_cornerRadius="4dp"
app:cpb_selectorIdle="@drawable/progress_button_state" app:cpb_selectorIdle="@drawable/progress_button_state"
app:cpb_textIdle="@string/activity_key_pair_register_button_title" /> app:cpb_textIdle="@string/activity_key_pair_register_or_restore_button_title_1" />
</LinearLayout> </LinearLayout>

View File

@ -1526,13 +1526,19 @@
<!-- Account details activity --> <!-- Account details activity -->
<string name="activity_account_details_title">Create Your Loki Messenger Account</string> <string name="activity_account_details_title">Create Your Loki Messenger Account</string>
<string name="activity_account_details_subtitle">Enter a name to be shown to your contacts</string> <string name="activity_account_details_subtitle">Enter a name to be shown to your contacts</string>
<string name="activity_account_details_name_edit_text_label">Display Name (Optional)</string>
<string name="activity_account_details_button_title">Next</string> <string name="activity_account_details_button_title">Next</string>
<!-- Key pair activity --> <!-- Key pair activity -->
<string name="activity_key_pair_title">Create Your Loki Messenger Account</string> <string name="activity_key_pair_title">Create Your Loki Messenger Account</string>
<string name="activity_key_pair_subtitle">Please save the seed below in a safe location. It can be used to restore your account if you lose access, or to migrate to a new device.</string> <string name="activity_key_pair_seed_explanation_1">Please save the seed below in a safe location. It can be used to restore your account if you lose access, or to migrate to a new device.</string>
<string name="activity_key_pair_seed_explanation_2">Restore your account by entering your seed below</string>
<string name="activity_key_pair_copy_button_title">Copy</string> <string name="activity_key_pair_copy_button_title">Copy</string>
<string name="activity_key_pair_mnemonic_edit_text_label">Your Seed</string>
<string name="activity_key_pair_toggle_mode_button_title_1">Restore Using Seed</string>
<string name="activity_key_pair_toggle_mode_button_title_2">Register a New Account</string>
<string name="activity_key_pair_mnemonic_copied_message">Copied to Clipboard</string> <string name="activity_key_pair_mnemonic_copied_message">Copied to Clipboard</string>
<string name="activity_key_pair_register_button_title">Register</string> <string name="activity_key_pair_register_or_restore_button_title_1">Register</string>
<string name="activity_key_pair_register_or_restore_button_title_2">Restore</string>
<!-- Settings activity --> <!-- Settings activity -->
<string name="activity_settings_share_public_key_button_title">Share Public Key</string> <string name="activity_settings_share_public_key_button_title">Share Public Key</string>
<string name="activity_settings_show_seed_button_title">Show Seed</string> <string name="activity_settings_show_seed_button_title">Show Seed</string>

View File

@ -5,6 +5,8 @@ import android.content.ClipboardManager
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.Toast import android.widget.Toast
import kotlinx.android.synthetic.main.activity_key_pair.* import kotlinx.android.synthetic.main.activity_key_pair.*
import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.ApplicationContext
@ -26,11 +28,17 @@ import java.io.FileOutputStream
class KeyPairActivity : BaseActionBarActivity() { class KeyPairActivity : BaseActionBarActivity() {
private lateinit var languageFileDirectory: File private lateinit var languageFileDirectory: File
private var mode = Mode.Register
set(newValue) { field = newValue; updateUI() }
private var keyPair: IdentityKeyPair? = null private var keyPair: IdentityKeyPair? = null
set(newValue) { field = newValue; updateMnemonic() } set(newValue) { field = newValue; updateMnemonic() }
private var mnemonic: String? = null private var mnemonic: String? = null
set(newValue) { field = newValue; updateMnemonicTextView() } set(newValue) { field = newValue; updateMnemonicTextView() }
// region Types
enum class Mode { Register, Restore }
// endregion
// region Lifecycle // region Lifecycle
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -38,7 +46,8 @@ class KeyPairActivity : BaseActionBarActivity() {
setUpLanguageFileDirectory() setUpLanguageFileDirectory()
updateKeyPair() updateKeyPair()
copyButton.setOnClickListener { copy() } copyButton.setOnClickListener { copy() }
registerButton.setOnClickListener { register() } toggleModeButton.setOnClickListener { toggleMode() }
registerOrRestoreButton.setOnClickListener { registerOrRestore() }
} }
// endregion // endregion
@ -71,6 +80,25 @@ class KeyPairActivity : BaseActionBarActivity() {
keyPair = IdentityKeyUtil.getIdentityKeyPair(this) keyPair = IdentityKeyUtil.getIdentityKeyPair(this)
} }
private fun updateUI() {
seedExplanationTextView1.visibility = if (mode == Mode.Register) View.VISIBLE else View.GONE
mnemonicTextView.visibility = if (mode == Mode.Register) View.VISIBLE else View.GONE
copyButton.visibility = if (mode == Mode.Register) View.VISIBLE else View.GONE
seedExplanationTextView2.visibility = if (mode == Mode.Restore) View.VISIBLE else View.GONE
mnemonicEditText.visibility = if (mode == Mode.Restore) View.VISIBLE else View.GONE
val toggleModeButtonTitleID = if (mode == Mode.Register) R.string.activity_key_pair_toggle_mode_button_title_1 else R.string.activity_key_pair_toggle_mode_button_title_2
toggleModeButton.setText(toggleModeButtonTitleID)
val registerOrRestoreButtonTitleID = if (mode == Mode.Register) R.string.activity_key_pair_register_or_restore_button_title_1 else R.string.activity_key_pair_register_or_restore_button_title_2
registerOrRestoreButton.setText(registerOrRestoreButtonTitleID)
if (mode == Mode.Restore) {
mnemonicEditText.requestFocus()
} else {
mnemonicEditText.clearFocus()
val inputMethodManager = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.hideSoftInputFromWindow(mnemonicEditText.windowToken, 0)
}
}
private fun updateMnemonic() { private fun updateMnemonic() {
mnemonic = MnemonicCodec(languageFileDirectory).encode(keyPair!!.hexEncodedPrivateKey) mnemonic = MnemonicCodec(languageFileDirectory).encode(keyPair!!.hexEncodedPrivateKey)
} }
@ -88,7 +116,14 @@ class KeyPairActivity : BaseActionBarActivity() {
Toast.makeText(this, R.string.activity_key_pair_mnemonic_copied_message, Toast.LENGTH_SHORT).show() Toast.makeText(this, R.string.activity_key_pair_mnemonic_copied_message, Toast.LENGTH_SHORT).show()
} }
private fun register() { private fun toggleMode() {
mode = when (mode) {
Mode.Register -> Mode.Restore
Mode.Restore -> Mode.Register
}
}
private fun registerOrRestore() {
val publicKey = keyPair!!.publicKey val publicKey = keyPair!!.publicKey
val hexEncodedPublicKey = keyPair!!.hexEncodedPublicKey val hexEncodedPublicKey = keyPair!!.hexEncodedPublicKey
val registrationID = KeyHelper.generateRegistrationId(false) val registrationID = KeyHelper.generateRegistrationId(false)