mirror of
https://codeberg.org/r4v3r23/mysu.git
synced 2024-11-09 23:50:02 +00:00
Add seed type toggle to onboarding screen
This commit is contained in:
parent
fc853dc55d
commit
5893c52c27
4 changed files with 125 additions and 34 deletions
|
@ -94,6 +94,9 @@ public class OnboardingFragment extends Fragment implements NodeSelectionBottomS
|
|||
private Button selectNodeButton;
|
||||
private SwitchCompat showXmrchanSwitch;
|
||||
private ImageView xmrchanOnboardingImage;
|
||||
private TextView seedTypeLabelTextView;
|
||||
private TextView seedTypeTextView;
|
||||
private TextView seedTypeDescTextView;
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
|
@ -122,6 +125,9 @@ public class OnboardingFragment extends Fragment implements NodeSelectionBottomS
|
|||
advancedOptionsLayout = view.findViewById(R.id.more_options_layout);
|
||||
showXmrchanSwitch = view.findViewById(R.id.show_xmrchan_switch);
|
||||
xmrchanOnboardingImage = view.findViewById(R.id.xmrchan_onboarding_imageview);
|
||||
seedTypeLabelTextView = view.findViewById(R.id.seed_type_label_textview);
|
||||
seedTypeTextView = view.findViewById(R.id.seed_type_name_textview);
|
||||
seedTypeDescTextView = view.findViewById(R.id.seed_type_desc_textview);
|
||||
|
||||
bindListeners();
|
||||
bindObservers();
|
||||
|
@ -141,6 +147,20 @@ public class OnboardingFragment extends Fragment implements NodeSelectionBottomS
|
|||
mViewModel.enableCreateButton.observe(getViewLifecycleOwner(), enable -> {
|
||||
createWalletButton.setEnabled(enable);
|
||||
});
|
||||
|
||||
mViewModel.seedType.observe(getViewLifecycleOwner(), seedType -> {
|
||||
seedTypeTextView.setText(seedType.toString());
|
||||
seedTypeDescTextView.setText(getText(seedType.getDescResId()));
|
||||
if(seedType == OnboardingViewModel.SeedType.LEGACY) {
|
||||
seedOffsetCheckbox.setVisibility(View.VISIBLE);
|
||||
walletRestoreHeightEditText.setVisibility(View.VISIBLE);
|
||||
walletPasswordEditText.setHint(getString(R.string.password_optional));
|
||||
} else {
|
||||
seedOffsetCheckbox.setVisibility(View.GONE);
|
||||
walletRestoreHeightEditText.setVisibility(View.GONE);
|
||||
walletPasswordEditText.setHint(getString(R.string.password_non_optional));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void bindListeners() {
|
||||
|
@ -198,16 +218,6 @@ public class OnboardingFragment extends Fragment implements NodeSelectionBottomS
|
|||
@Override
|
||||
public void afterTextChanged(Editable editable) {
|
||||
String text = editable.toString();
|
||||
OnboardingViewModel.SeedType seedType = mViewModel.getMnemonicType(text);
|
||||
if(seedType == OnboardingViewModel.SeedType.LEGACY) {
|
||||
seedOffsetCheckbox.setVisibility(View.VISIBLE);
|
||||
walletRestoreHeightEditText.setVisibility(View.VISIBLE);
|
||||
walletPasswordEditText.setHint(getString(R.string.password_optional));
|
||||
} else {
|
||||
seedOffsetCheckbox.setVisibility(View.GONE);
|
||||
walletRestoreHeightEditText.setVisibility(View.GONE);
|
||||
walletPasswordEditText.setHint(getString(R.string.password_non_optional));
|
||||
}
|
||||
|
||||
if (text.isEmpty()) {
|
||||
createWalletButton.setText(R.string.create_wallet);
|
||||
|
@ -216,6 +226,11 @@ public class OnboardingFragment extends Fragment implements NodeSelectionBottomS
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
seedTypeLabelTextView.setOnClickListener(v -> toggleSeedType());
|
||||
seedTypeTextView.setOnClickListener(v -> toggleSeedType());
|
||||
seedTypeDescTextView.setOnClickListener(v -> toggleSeedType());
|
||||
|
||||
torSwitch.setOnCheckedChangeListener((compoundButton, b) -> {
|
||||
PrefService.getInstance().edit().putBoolean(Constants.PREF_USES_TOR, b).apply();
|
||||
if (b) {
|
||||
|
@ -257,6 +272,19 @@ public class OnboardingFragment extends Fragment implements NodeSelectionBottomS
|
|||
});
|
||||
}
|
||||
|
||||
private void toggleSeedType() {
|
||||
OnboardingViewModel.SeedType seedType = mViewModel.seedType.getValue();
|
||||
if(seedType == null) return;
|
||||
OnboardingViewModel.SeedType newSeedType = OnboardingViewModel.SeedType.UNKNOWN;
|
||||
if(seedType == OnboardingViewModel.SeedType.POLYSEED) {
|
||||
newSeedType = OnboardingViewModel.SeedType.LEGACY;
|
||||
} else if(seedType == OnboardingViewModel.SeedType.LEGACY) {
|
||||
newSeedType = OnboardingViewModel.SeedType.POLYSEED;
|
||||
}
|
||||
|
||||
mViewModel.setSeedType(newSeedType);
|
||||
}
|
||||
|
||||
private void prepareDefaultNode() {
|
||||
PrefService.getInstance().getNode();
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@ public class OnboardingViewModel extends ViewModel {
|
|||
public LiveData<Boolean> showMoreOptions = _showMoreOptions;
|
||||
private final MutableLiveData<Boolean> _enableCreateButton = new MutableLiveData<>(true);
|
||||
public LiveData<Boolean> enableCreateButton = _enableCreateButton;
|
||||
private final MutableLiveData<SeedType> _seedType = new MutableLiveData<>(SeedType.POLYSEED);
|
||||
public LiveData<SeedType> seedType = _seedType;
|
||||
private String proxyAddress = "";
|
||||
private String proxyPort = "";
|
||||
|
||||
|
@ -53,6 +55,10 @@ public class OnboardingViewModel extends ViewModel {
|
|||
});
|
||||
}
|
||||
|
||||
public void setSeedType(SeedType seedType) {
|
||||
this._seedType.setValue(seedType);
|
||||
}
|
||||
|
||||
|
||||
public void setProxyAddress(String address) {
|
||||
this.proxyAddress = address;
|
||||
|
@ -65,13 +71,11 @@ public class OnboardingViewModel extends ViewModel {
|
|||
public void createOrImportWallet(Activity mainActivity, String walletPassword, String confirmedPassword, String walletSeed, String restoreHeightText, boolean useOffset) {
|
||||
MoneroApplication application = (MoneroApplication)mainActivity.getApplication();
|
||||
application.getExecutor().execute(() -> {
|
||||
mainActivity.runOnUiThread(() -> {
|
||||
_enableCreateButton.setValue(false);
|
||||
});
|
||||
_enableCreateButton.postValue(false);
|
||||
String offset = useOffset ? walletPassword : "";
|
||||
if (!walletPassword.isEmpty()) {
|
||||
if(!walletPassword.equals(confirmedPassword)) {
|
||||
_enableCreateButton.setValue(true);
|
||||
_enableCreateButton.postValue(true);
|
||||
mainActivity.runOnUiThread(() -> Toast.makeText(mainActivity, application.getString(R.string.invalid_confirmed_password), Toast.LENGTH_SHORT).show());
|
||||
return;
|
||||
}
|
||||
|
@ -85,19 +89,29 @@ public class OnboardingViewModel extends ViewModel {
|
|||
}
|
||||
|
||||
if (walletSeed.isEmpty()) {
|
||||
SeedType seedTypeValue = seedType.getValue();
|
||||
if(seedTypeValue == null) return;
|
||||
|
||||
if(seedTypeValue == SeedType.POLYSEED) {
|
||||
if(offset.isEmpty()) {
|
||||
mainActivity.runOnUiThread(() -> {
|
||||
_enableCreateButton.setValue(true);
|
||||
_enableCreateButton.postValue(true);
|
||||
Toast.makeText(mainActivity, application.getString(R.string.invalid_empty_passphrase), Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
wallet = WalletManager.getInstance().createWalletPolyseed(walletFile, walletPassword, offset, Constants.MNEMONIC_LANGUAGE);
|
||||
}
|
||||
} else if(seedTypeValue == SeedType.LEGACY) {
|
||||
File tmpWalletFile = new File(mainActivity.getApplicationInfo().dataDir, Constants.WALLET_NAME + "_tmp");
|
||||
Wallet tmpWallet = createTempWallet(tmpWalletFile); //we do this to get seed, then recover wallet so we can use seed offset
|
||||
wallet = WalletManager.getInstance().recoveryWallet(walletFile, walletPassword, tmpWallet.getSeed(""), offset, restoreHeight);
|
||||
tmpWalletFile.delete();
|
||||
}
|
||||
} else {
|
||||
if (getMnemonicType(walletSeed) == SeedType.UNKNOWN) {
|
||||
mainActivity.runOnUiThread(() -> {
|
||||
_enableCreateButton.setValue(true);
|
||||
_enableCreateButton.postValue(true);
|
||||
Toast.makeText(mainActivity, application.getString(R.string.invalid_mnemonic_code), Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
return;
|
||||
|
@ -110,14 +124,14 @@ public class OnboardingViewModel extends ViewModel {
|
|||
Wallet.Status walletStatus = wallet.getStatus();
|
||||
wallet.close();
|
||||
boolean ok = walletStatus.isOk();
|
||||
//walletFile.delete(); // cache is broken for some reason when recovering wallets. delete the file here. this happens in monerujo too.
|
||||
walletFile.delete(); // cache is broken for some reason when recovering wallets. delete the file here. this happens in monerujo too.
|
||||
|
||||
if (ok) {
|
||||
((MainActivity)mainActivity).init(walletFile, walletPassword);
|
||||
mainActivity.runOnUiThread(mainActivity::onBackPressed);
|
||||
} else {
|
||||
mainActivity.runOnUiThread(() -> {
|
||||
_enableCreateButton.setValue(true);
|
||||
_enableCreateButton.postValue(true);
|
||||
Toast.makeText(mainActivity, application.getString(R.string.create_wallet_failed, walletStatus.getErrorString()), Toast.LENGTH_SHORT).show();
|
||||
});
|
||||
}
|
||||
|
@ -132,18 +146,34 @@ public class OnboardingViewModel extends ViewModel {
|
|||
|
||||
public SeedType getMnemonicType(String seed) {
|
||||
String[] words = seed.split("\\s");
|
||||
if(words.length == 16) {
|
||||
SeedType seedTypeValue = seedType.getValue();
|
||||
if(seedTypeValue == null) return SeedType.LEGACY;
|
||||
if(words.length == 16 && seedTypeValue == SeedType.POLYSEED) {
|
||||
return SeedType.POLYSEED;
|
||||
} else if (words.length == 25){
|
||||
} else if (words.length == 25 && seedTypeValue == SeedType.LEGACY){
|
||||
return SeedType.LEGACY;
|
||||
} else {
|
||||
return SeedType.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
private Wallet createTempWallet(File tmpWalletFile) {
|
||||
return WalletManager.getInstance().createWallet(tmpWalletFile, "", Constants.MNEMONIC_LANGUAGE, 0);
|
||||
}
|
||||
|
||||
public enum SeedType {
|
||||
LEGACY,
|
||||
POLYSEED,
|
||||
UNKNOWN
|
||||
LEGACY(R.string.seed_desc_legacy),
|
||||
POLYSEED(R.string.seed_desc_polyseed),
|
||||
UNKNOWN(0);
|
||||
|
||||
private int descResId;
|
||||
|
||||
SeedType(int descResId) {
|
||||
this.descResId = descResId;
|
||||
}
|
||||
|
||||
public int getDescResId() {
|
||||
return descResId;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,8 +7,9 @@
|
|||
<ImageView
|
||||
android:id="@+id/xmrchan_onboarding_imageview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="fitEnd"
|
||||
android:adjustViewBounds="false"
|
||||
android:src="@drawable/xmrchan_half"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
<ScrollView
|
||||
|
@ -67,11 +68,12 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/more_options"
|
||||
android:textStyle="bold"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingBottom="4dp"
|
||||
android:textSize="18sp"
|
||||
app:layout_constraintBottom_toTopOf="@id/more_options_layout"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
|
@ -132,10 +134,39 @@
|
|||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/wallet_seed_edittext"
|
||||
app:layout_constraintBottom_toTopOf="@id/seed_type_label_textview"
|
||||
app:layout_constraintTop_toBottomOf="@id/show_xmrchan_switch"
|
||||
tools:ignore="SpeakableTextPresentCheck" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/seed_type_label_textview"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Seed version"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/seed_type_name_textview"
|
||||
app:layout_constraintTop_toBottomOf="@id/select_node_button"
|
||||
app:layout_constraintBottom_toTopOf="@id/seed_type_name_textview"/>
|
||||
<TextView
|
||||
android:id="@+id/seed_type_name_textview"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="POLYSEED"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/seed_type_label_textview"
|
||||
app:layout_constraintBottom_toBottomOf="@id/seed_type_label_textview"/>
|
||||
<TextView
|
||||
android:id="@+id/seed_type_desc_textview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/oled_addressListColor"
|
||||
android:paddingBottom="16dp"
|
||||
android:paddingTop="8dp"
|
||||
android:text="16 words instead of 25; just as secure."
|
||||
app:layout_constraintTop_toBottomOf="@id/seed_type_label_textview"
|
||||
app:layout_constraintBottom_toTopOf="@id/wallet_seed_edittext"/>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/wallet_seed_edittext"
|
||||
android:layout_width="0dp"
|
||||
|
@ -147,7 +178,7 @@
|
|||
app:layout_constraintBottom_toTopOf="@id/wallet_restore_height_edittext"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/select_node_button" />
|
||||
app:layout_constraintTop_toBottomOf="@id/seed_type_desc_textview" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/wallet_restore_height_edittext"
|
||||
|
|
|
@ -153,5 +153,7 @@
|
|||
<string name="scan_qr_code_for_address_field">Scan QR code for address field</string>
|
||||
<string name="copy_transaction_hash">Copy transaction hash</string>
|
||||
<string name="copy_transaction_addr">Copy transaction address</string>
|
||||
<string name="seed_desc_polyseed">16 words instead of 25; just as secure, but not supported in as many wallets right now. In Mysu, seed passphrase is enforced for these wallets.</string>
|
||||
<string name="seed_desc_legacy">Older, 25 word seed; supported in all Monero wallets. In Mysu, seed passphrase is not enforced for these wallets.</string>
|
||||
|
||||
</resources>
|
||||
|
|
Loading…
Reference in a new issue