1
mirror of https://github.com/m2049r/xmrwallet synced 2025-09-03 08:23:04 +02:00

Compare commits

...

49 Commits

Author SHA1 Message Date
m2049r
1829d30b61 Restyle UI (#690)
* enable testnet flavor
* v0.17.1.0
* migrate to androidx & material
* new color themes
* bump version v1.15.2
2020-10-16 02:52:08 +02:00
m2049r
e5b15b7816 always apply tx_amount from qr code (#687) 2020-09-27 11:00:57 +02:00
m2049r
7206857a5b bump version v1.14.8 2020-09-25 21:49:59 +02:00
m2049r
85d84d09ee fix crash when sending btc (#686) 2020-09-25 20:08:07 +02:00
m2049r
c6a1b503bc bump version 1.14.7 2020-09-23 11:20:16 +02:00
m2049r
8bda7aa0cf fix crash if auth failed (#684) 2020-09-23 11:19:28 +02:00
m2049r
97fb0a5483 bump version 1.14.6 2020-09-21 22:11:35 +02:00
m2049r
fc950c6772 fix onboarding layout (#683) 2020-09-21 22:10:51 +02:00
m2049r
46add5e927 bump version v1.14.5 2020-09-21 14:37:51 +02:00
m2049r
fa0692ceab force agree for fingerprint send (#682) 2020-09-21 14:36:17 +02:00
m2049r
ff4f4a1c2c remove notices covered by onboarding (#681) 2020-09-21 14:35:50 +02:00
m2049r
79abb89725 disable button on finish onbaording (#680) 2020-09-21 14:35:25 +02:00
m2049r
ef8301fd6f bump version v1.14.4 2020-09-18 22:09:32 +02:00
hiddener
3a15c842ff updated Romanian translation 2020-09-18 22:01:41 +02:00
m2049r
1697da55b5 only update if we still have a wallet 2020-09-18 22:00:14 +02:00
m2049r
454f3e412a don't do stuff if the wallet is already closed 2020-09-18 22:00:14 +02:00
m2049r
d803a1e220 remove unused resources (#678) 2020-09-18 21:59:38 +02:00
m2049r
f2fe781cb5 update restore heights 2020-09-17 10:18:58 +02:00
m2049r
dcf60ae193 bump version v1.14.3 2020-09-17 09:35:28 +02:00
m2049r
ffdf54c2e1 Merge pull request #677 from m2049r/fix_various
Various fixes & tweaks
2020-09-17 09:34:04 +02:00
m2049r
c060a2ab88 don't show onboarding every time 2020-09-16 19:59:58 +02:00
m2049r
05fc654f3a clean up code 2020-09-16 18:56:27 +02:00
m2049r
c32d157150 monero addresses are 95 characters 2020-09-16 17:51:47 +02:00
m2049r
74e9278baa MainActivity must be singleTop 2020-09-16 17:45:07 +02:00
m2049r
e41e344d63 bump version v1.14.2 2020-09-14 18:16:35 +02:00
m2049r
e66875437d always show onboarding 2020-09-14 18:14:38 +02:00
m2049r
c1d2db3d7d onboarding tweaks & version bump (#676) 2020-09-14 00:24:57 +02:00
m2049r
0c9a2f5e01 fixups 2020-09-13 18:52:26 +02:00
m2049r
64616e3921 onboarding (#675)
Co-authored-by: Stephan <stephan.hagios@gmail.com>
2020-09-13 18:34:22 +02:00
m2049r
82b4d66987 allow spend with fingerprint only (#674) 2020-09-13 18:26:36 +02:00
m2049r
10f2bc6561 upgrade monero core (#673) 2020-09-05 11:01:34 +02:00
m2049r
2ed9a78d9e upgrade gradle 2020-07-16 14:14:26 +02:00
m2049r
ca19f32f8f bump version 2020-07-06 15:00:10 +02:00
m2049r
4431d74051 Fix for Ledger protocol v3 (#670)
* update protocol to V3 for Monero App v1.6.0
2020-07-06 14:59:38 +02:00
TheFuzzStone
f00da6ecda Renamed folder to '*-uk' and files to *-uk. (#666)
* Renamed folder to '*-uk' and files to `*-uk`. 
Changed '&apos;' to '\''

* Renamed file names
2020-06-20 18:07:43 +02:00
m2049r
1cecd0b718 xmr.to v3 API (#667) 2020-06-19 19:17:38 +02:00
m2049r
a0d6117bbb don't keepTimestampsInApk 2020-06-06 09:46:28 +02:00
m2049r
0b0648a172 upgrade dev env 2020-06-05 08:56:02 +02:00
m2049r
775dcf01ae bump version 2020-06-01 20:14:03 +02:00
m2049r
aed4051d44 Merge branch 'TheFuzzStone-master' 2020-06-01 20:09:51 +02:00
m2049r
a586c0781a renamed directory to match locale 2020-06-01 20:08:22 +02:00
m2049r
616d93cb18 replace &apos; 2020-06-01 20:04:55 +02:00
v1docq47
73d9cb6d58 Update for Russian translation (#649)
Update:
 - strings.xml

Co-authored-by: m2049r <m2049r@monerujo.io>
2020-06-01 19:57:33 +02:00
m2049r
9846e8b5cf fix progress bar (#665) 2020-06-01 19:56:24 +02:00
m2049r
aa66a12dac Merge branch 'master' into master 2020-06-01 13:43:16 +02:00
m2049r
65ce9b0889 Update blockheight (#664)
* update through june
2020-06-01 10:04:09 +02:00
m2049r
291e311b8a Enable rescan on wallet (from menu) (#663)
* rescan
2020-06-01 10:03:36 +02:00
m2049r
41290f51fd Upgrade to monero v0.16.0.0 (#662)
* upgrade to monero core v0.16.0.0

* hearts for node favs
2020-06-01 10:02:22 +02:00
TheFuzzStone
835a35c6a8 Updating Ukranian language 2020-02-13 13:49:52 +02:00
248 changed files with 7786 additions and 2461 deletions

1
.gitignore vendored
View File

@@ -14,3 +14,4 @@
/app/prodMainnet
/app/alphaStagenet
/app/prodStagenet
/app/.cxx

View File

@@ -2,15 +2,14 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion 28
buildToolsVersion '28.0.3'
buildToolsVersion '29.0.2'
defaultConfig {
applicationId "com.m2049r.xmrwallet"
minSdkVersion 21
targetSdkVersion 28
versionCode 203
versionName "1.12.13 'Caerbannog'"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
versionCode 502
versionName "1.15.2 'Dark Fork'"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags "-std=c++11"
@@ -18,6 +17,11 @@ android {
}
}
}
bundle {
language {
enableSplit = false
}
}
flavorDimensions 'type', 'net'
productFlavors {
@@ -29,6 +33,11 @@ android {
applicationIdSuffix '.stage'
versionNameSuffix ' (stage)'
}
devnet {
dimension 'net'
applicationIdSuffix '.test'
versionNameSuffix ' (test)'
}
alpha {
dimension 'type'
applicationIdSuffix '.alpha'
@@ -71,7 +80,8 @@ android {
def availableLocales = ["en"]
new File("app/src/main/res/").eachFileMatch(~/^values-.*/) { file ->
def languageTag = file.name.substring(7).replace("-r", "-")
availableLocales.add(languageTag)
if (languageTag != "night")
availableLocales.add(languageTag)
}
// APKs for the same app that all have the same version information.
@@ -93,36 +103,41 @@ android {
outputFileName = "$rootProject.ext.apkName-" + v + "_" + abiName + ".apk"
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation "com.android.support:appcompat-v7:$rootProject.ext.supportVersion"
implementation "com.android.support:design:$rootProject.ext.supportVersion"
implementation "com.android.support:support-v4:$rootProject.ext.supportVersion"
implementation "com.android.support:recyclerview-v7:$rootProject.ext.supportVersion"
implementation "com.android.support:cardview-v7:$rootProject.ext.supportVersion"
implementation "com.android.support:swiperefreshlayout:$rootProject.ext.supportVersion"
implementation 'me.dm7.barcodescanner:zxing:1.9.8'
implementation 'androidx.core:core:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation group: 'com.google.android.material', name: 'material', version: '1.3.0-alpha03'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.2.0-alpha01'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
implementation 'me.dm7.barcodescanner:zxing:1.9.8'
implementation "com.squareup.okhttp3:okhttp:$rootProject.ext.okHttpVersion"
implementation "com.burgstaller:okhttp-digest:1.18"
implementation "com.burgstaller:okhttp-digest:2.0"
implementation "com.jakewharton.timber:timber:$rootProject.ext.timberVersion"
implementation 'com.nulab-inc:zxcvbn:1.2.3'
implementation 'com.nulab-inc:zxcvbn:1.3.0'
implementation 'dnsjava:dnsjava:2.1.8'
implementation 'org.jitsi:dnssecjava:1.1.3'
implementation 'org.slf4j:slf4j-nop:1.7.25'
implementation 'dnsjava:dnsjava:2.1.9'
implementation 'org.jitsi:dnssecjava:1.2.0'
implementation 'org.slf4j:slf4j-nop:1.7.30'
implementation 'com.github.brnunes:swipeablerecyclerview:1.0.2'
// https://mvnrepository.com/artifact/com.github.aelstad/keccakj
implementation 'com.github.aelstad:keccakj:1.1.0'
testImplementation "junit:junit:$rootProject.ext.junitVersion"
testImplementation "org.mockito:mockito-all:$rootProject.ext.mockitoVersion"
testImplementation "com.squareup.okhttp3:mockwebserver:$rootProject.ext.okHttpVersion"
testImplementation 'org.json:json:20180813'
testImplementation 'net.jodah:concurrentunit:0.4.4'
}

View File

@@ -20,24 +20,28 @@
android:supportsRtl="true"
android:theme="@style/MyMaterialTheme"
android:usesCleartextTraffic="true">
<activity
android:name=".WalletActivity"
android:configChanges="orientation|keyboardHidden"
android:label="@string/wallet_activity_name"
android:launchMode="singleTask"
android:screenOrientation="behind" />
<activity
android:name=".LoginActivity"
android:configChanges="orientation|keyboardHidden"
android:label="@string/app_name"
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|uiMode"
android:launchMode="singleTop"
android:screenOrientation="locked">
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".WalletActivity"
android:configChanges="orientation|keyboardHidden|uiMode"
android:label="@string/wallet_activity_name"
android:launchMode="singleTask"
android:screenOrientation="behind"/>
<activity
android:name=".LoginActivity"
android:configChanges="orientation|keyboardHidden|uiMode"
android:label="@string/app_name"
android:launchMode="singleTop"
android:screenOrientation="locked">
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
@@ -62,6 +66,11 @@
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/usb_device_filter" />
</activity>
<activity
android:name=".onboarding.OnBoardingActivity"
android:configChanges="orientation|keyboardHidden|uiMode"
android:launchMode="singleTask"
android:screenOrientation="portrait" />
<service
android:name=".service.WalletService"
@@ -70,7 +79,7 @@
android:label="Monero Wallet Service" />
<provider
android:name="android.support.v4.content.FileProvider"
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
@@ -79,4 +88,4 @@
android:resource="@xml/filepaths" />
</provider>
</application>
</manifest>
</manifest>

File diff suppressed because it is too large Load Diff

View File

@@ -15,9 +15,9 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
import android.support.annotation.CallSuper;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import androidx.annotation.CallSuper;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import android.widget.Toast;
import com.m2049r.xmrwallet.data.BarcodeData;

View File

@@ -17,13 +17,9 @@
package com.m2049r.xmrwallet;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.TextInputLayout;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.Html;
import android.text.InputType;
@@ -38,9 +34,15 @@ import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Switch;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.switchmaterial.SwitchMaterial;
import com.google.android.material.textfield.TextInputLayout;
import com.m2049r.xmrwallet.model.Wallet;
import com.m2049r.xmrwallet.model.WalletManager;
import com.m2049r.xmrwallet.util.FingerprintHelper;
@@ -202,13 +204,13 @@ public class GenerateFragment extends Fragment {
if (FingerprintHelper.isDeviceSupported(getContext())) {
llFingerprintAuth.setVisibility(View.VISIBLE);
final Switch swFingerprintAllowed = (Switch) llFingerprintAuth.getChildAt(0);
final SwitchMaterial swFingerprintAllowed = (SwitchMaterial) llFingerprintAuth.getChildAt(0);
swFingerprintAllowed.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!swFingerprintAllowed.isChecked()) return;
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getActivity());
builder.setMessage(Html.fromHtml(getString(R.string.generate_fingerprint_warn)))
.setCancelable(false)
.setPositiveButton(getString(R.string.label_ok), null)
@@ -507,7 +509,7 @@ public class GenerateFragment extends Fragment {
String name = etWalletName.getEditText().getText().toString();
String password = etWalletPassword.getEditText().getText().toString();
boolean fingerprintAuthAllowed = ((Switch) llFingerprintAuth.getChildAt(0)).isChecked();
boolean fingerprintAuthAllowed = ((SwitchMaterial) llFingerprintAuth.getChildAt(0)).isChecked();
// create the real wallet password
String crazyPass = KeyStoreHelper.getCrazyPass(getActivity(), password);
@@ -646,7 +648,7 @@ public class GenerateFragment extends Fragment {
if (ledgerDialog != null) return;
final Activity activity = getActivity();
View promptsView = getLayoutInflater().inflate(R.layout.prompt_ledger_seed, null);
android.app.AlertDialog.Builder alertDialogBuilder = new android.app.AlertDialog.Builder(activity);
MaterialAlertDialogBuilder alertDialogBuilder = new MaterialAlertDialogBuilder(activity);
alertDialogBuilder.setView(promptsView);
final TextInputLayout etSeed = promptsView.findViewById(R.id.etSeed);

View File

@@ -16,14 +16,10 @@
package com.m2049r.xmrwallet;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.TextInputLayout;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.Html;
import android.text.TextWatcher;
@@ -40,10 +36,17 @@ import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.ScrollView;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.switchmaterial.SwitchMaterial;
import com.google.android.material.textfield.TextInputLayout;
import com.m2049r.xmrwallet.ledger.Ledger;
import com.m2049r.xmrwallet.ledger.LedgerProgressDialog;
import com.m2049r.xmrwallet.model.NetworkType;
@@ -118,31 +121,11 @@ public class GenerateReviewFragment extends Fragment {
tvWalletSpendKey.setTextIsSelectable(allowCopy);
tvWalletPassword.setTextIsSelectable(allowCopy);
bAccept.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
acceptWallet();
}
});
view.findViewById(R.id.bCopyViewKey).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
copyViewKey();
}
});
bCopyAddress.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
copyAddress();
}
});
bCopyAddress.setClickable(false);
view.findViewById(R.id.bAdvancedInfo).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showAdvancedInfo();
}
});
bAccept.setOnClickListener(v -> acceptWallet());
view.findViewById(R.id.bCopyViewKey).setOnClickListener(v -> copyViewKey());
bCopyAddress.setEnabled(false);
bCopyAddress.setOnClickListener(v -> copyAddress());
view.findViewById(R.id.bAdvancedInfo).setOnClickListener(v -> showAdvancedInfo());
Bundle args = getArguments();
type = args.getString(REQUEST_TYPE);
@@ -287,8 +270,7 @@ public class GenerateReviewFragment extends Fragment {
showAdvanced = true;
}
if (showAdvanced) bAdvancedInfo.setVisibility(View.VISIBLE);
bCopyAddress.setClickable(true);
bCopyAddress.setImageResource(R.drawable.ic_content_copy_black_24dp);
bCopyAddress.setEnabled(true);
activityCallback.setTitle(name, getString(R.string.details_title));
activityCallback.setToolbarButton(
GenerateReviewFragment.VIEW_TYPE_ACCEPT.equals(type) ? Toolbar.BUTTON_NONE : Toolbar.BUTTON_BACK);
@@ -352,7 +334,7 @@ public class GenerateReviewFragment extends Fragment {
}
@Override
public void onAttach(Context context) {
public void onAttach(@NonNull Context context) {
super.onAttach(context);
if (context instanceof Listener) {
this.activityCallback = (Listener) context;
@@ -399,7 +381,7 @@ public class GenerateReviewFragment extends Fragment {
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
String type = getArguments().getString(REQUEST_TYPE); // intance variable <type> not set yet
if (GenerateReviewFragment.VIEW_TYPE_ACCEPT.equals(type)) {
inflater.inflate(R.menu.wallet_details_help_menu, menu);
@@ -448,7 +430,7 @@ public class GenerateReviewFragment extends Fragment {
protected Boolean doInBackground(String... params) {
if (params.length != 2) return false;
final String userPassword = params[0];
final boolean fingerPassValid = Boolean.valueOf(params[1]);
final boolean fingerPassValid = Boolean.parseBoolean(params[1]);
newPassword = KeyStoreHelper.getCrazyPass(getActivity(), userPassword);
final boolean success = changeWalletPassword(newPassword);
if (success) {
@@ -488,7 +470,7 @@ public class GenerateReviewFragment extends Fragment {
LayoutInflater li = LayoutInflater.from(getActivity());
View promptsView = li.inflate(R.layout.prompt_changepw, null);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity());
AlertDialog.Builder alertDialogBuilder = new MaterialAlertDialogBuilder(getActivity());
alertDialogBuilder.setView(promptsView);
final TextInputLayout etPasswordA = promptsView.findViewById(R.id.etWalletPasswordA);
@@ -498,7 +480,7 @@ public class GenerateReviewFragment extends Fragment {
etPasswordB.setHint(getString(R.string.prompt_changepwB, walletName));
LinearLayout llFingerprintAuth = promptsView.findViewById(R.id.llFingerprintAuth);
final Switch swFingerprintAllowed = (Switch) llFingerprintAuth.getChildAt(0);
final SwitchMaterial swFingerprintAllowed = (SwitchMaterial) llFingerprintAuth.getChildAt(0);
if (FingerprintHelper.isDeviceSupported(getActivity())) {
llFingerprintAuth.setVisibility(View.VISIBLE);
@@ -507,7 +489,7 @@ public class GenerateReviewFragment extends Fragment {
public void onClick(View view) {
if (!swFingerprintAllowed.isChecked()) return;
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(getActivity());
builder.setMessage(Html.fromHtml(getString(R.string.generate_fingerprint_warn)))
.setCancelable(false)
.setPositiveButton(getString(R.string.label_ok), null)
@@ -596,7 +578,7 @@ public class GenerateReviewFragment extends Fragment {
etPasswordA.setError(getString(R.string.generate_empty_passwordB));
} else if (!newPasswordA.equals(newPasswordB)) {
etPasswordB.setError(getString(R.string.generate_bad_passwordB));
} else if (newPasswordA.equals(newPasswordB)) {
} else {
new AsyncChangePassword().execute(newPasswordA, Boolean.toString(swFingerprintAllowed.isChecked()));
Helper.hideKeyboardAlways(getActivity());
openDialog.dismiss();
@@ -619,7 +601,7 @@ public class GenerateReviewFragment extends Fragment {
etPasswordA.setError(getString(R.string.generate_empty_passwordB));
} else if (!newPasswordA.equals(newPasswordB)) {
etPasswordB.setError(getString(R.string.generate_bad_passwordB));
} else if (newPasswordA.equals(newPasswordB)) {
} else {
new AsyncChangePassword().execute(newPasswordA, Boolean.toString(swFingerprintAllowed.isChecked()));
Helper.hideKeyboardAlways(getActivity());
openDialog.dismiss();

View File

@@ -16,7 +16,6 @@
package com.m2049r.xmrwallet;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -30,10 +29,6 @@ import android.hardware.usb.UsbManager;
import android.media.MediaScannerConnection;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MenuItem;
@@ -43,6 +38,14 @@ import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.m2049r.xmrwallet.data.Node;
import com.m2049r.xmrwallet.data.NodeInfo;
import com.m2049r.xmrwallet.dialog.AboutFragment;
@@ -55,10 +58,13 @@ import com.m2049r.xmrwallet.model.NetworkType;
import com.m2049r.xmrwallet.model.Wallet;
import com.m2049r.xmrwallet.model.WalletManager;
import com.m2049r.xmrwallet.service.WalletService;
import com.m2049r.xmrwallet.util.ColorHelper;
import com.m2049r.xmrwallet.util.DayNightMode;
import com.m2049r.xmrwallet.util.Helper;
import com.m2049r.xmrwallet.util.KeyStoreHelper;
import com.m2049r.xmrwallet.util.LocaleHelper;
import com.m2049r.xmrwallet.util.MoneroThreadPoolExecutor;
import com.m2049r.xmrwallet.util.NightmodeHelper;
import com.m2049r.xmrwallet.widget.Toolbar;
import java.io.File;
@@ -69,7 +75,6 @@ import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
@@ -85,6 +90,7 @@ public class LoginActivity extends BaseActivity
private static final String GENERATE_STACK = "gen";
private static final String NODES_PREFS_NAME = "nodes";
private static final String PREF_DAEMON_TESTNET = "daemon_testnet";
private static final String PREF_DAEMON_STAGENET = "daemon_stagenet";
private static final String PREF_DAEMON_MAINNET = "daemon_mainnet";
@@ -163,6 +169,10 @@ public class LoginActivity extends BaseActivity
loadLegacyList(sharedPref.getString(PREF_DAEMON_STAGENET, null));
sharedPref.edit().remove(PREF_DAEMON_STAGENET).apply();
break;
case NetworkType_Testnet:
loadLegacyList(sharedPref.getString(PREF_DAEMON_TESTNET, null));
sharedPref.edit().remove(PREF_DAEMON_TESTNET).apply();
break;
default:
throw new IllegalStateException("unsupported net " + WalletManager.getInstance().getNetworkType());
}
@@ -315,10 +325,14 @@ public class LoginActivity extends BaseActivity
if (WalletManager.getInstance().walletExists(walletFile)) {
Helper.promptPassword(LoginActivity.this, walletName, true, new Helper.PasswordAction() {
@Override
public void action(String walletName, String password, boolean fingerprintUsed) {
public void act(String walletName, String password, boolean fingerprintUsed) {
if (checkDevice(walletName, password))
startDetails(walletFile, password, GenerateReviewFragment.VIEW_TYPE_DETAILS);
}
@Override
public void fail(String walletName, String password, boolean fingerprintUsed) {
}
});
} else { // this cannot really happen as we prefilter choices
Timber.e("Wallet missing: %s", walletName);
@@ -333,8 +347,8 @@ public class LoginActivity extends BaseActivity
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
AlertDialog diag = builder.setMessage(getString(R.string.details_alert_message))
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(this);
builder.setMessage(getString(R.string.details_alert_message))
.setPositiveButton(getString(R.string.details_alert_yes), dialogClickListener)
.setNegativeButton(getString(R.string.details_alert_no), dialogClickListener)
.show();
@@ -348,10 +362,14 @@ public class LoginActivity extends BaseActivity
if (WalletManager.getInstance().walletExists(walletFile)) {
Helper.promptPassword(LoginActivity.this, walletName, false, new Helper.PasswordAction() {
@Override
public void action(String walletName, String password, boolean fingerprintUsed) {
public void act(String walletName, String password, boolean fingerprintUsed) {
if (checkDevice(walletName, password))
startReceive(walletFile, password);
}
@Override
public void fail(String walletName, String password, boolean fingerprintUsed) {
}
});
} else { // this cannot really happen as we prefilter choices
Toast.makeText(this, getString(R.string.bad_wallet), Toast.LENGTH_SHORT).show();
@@ -418,7 +436,7 @@ public class LoginActivity extends BaseActivity
LayoutInflater li = LayoutInflater.from(this);
View promptsView = li.inflate(R.layout.prompt_rename, null);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
AlertDialog.Builder alertDialogBuilder = new MaterialAlertDialogBuilder(this);
alertDialogBuilder.setView(promptsView);
final EditText etRename = promptsView.findViewById(R.id.etRename);
@@ -573,7 +591,7 @@ public class LoginActivity extends BaseActivity
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(this);
builder.setMessage(getString(R.string.archive_alert_message))
.setTitle(walletName)
.setPositiveButton(getString(R.string.archive_alert_yes), dialogClickListener)
@@ -645,11 +663,11 @@ public class LoginActivity extends BaseActivity
break;
case NetworkType_Testnet:
toolbar.setSubtitle(getString(R.string.connect_testnet));
toolbar.setBackgroundResource(R.color.colorPrimaryDark);
toolbar.setBackgroundResource(ColorHelper.getThemedResourceId(this, R.attr.colorPrimaryDark));
break;
case NetworkType_Stagenet:
toolbar.setSubtitle(getString(R.string.connect_stagenet));
toolbar.setBackgroundResource(R.color.colorPrimaryDark);
toolbar.setBackgroundResource(ColorHelper.getThemedResourceId(this, R.attr.colorPrimaryDark));
break;
default:
throw new IllegalStateException("NetworkType unknown: " + net);
@@ -1116,41 +1134,54 @@ public class LoginActivity extends BaseActivity
public void onChangeLocale() {
final ArrayList<Locale> availableLocales = LocaleHelper.getAvailableLocales(LoginActivity.this);
String[] localeDisplayName = new String[1 + availableLocales.size()];
Collections.sort(availableLocales, new Comparator<Locale>() {
@Override
public int compare(Locale locale1, Locale locale2) {
String localeString1 = LocaleHelper.getDisplayName(locale1, true);
String localeString2 = LocaleHelper.getDisplayName(locale2, true);
return localeString1.compareTo(localeString2);
}
Collections.sort(availableLocales, (locale1, locale2) -> {
String localeString1 = LocaleHelper.getDisplayName(locale1, true);
String localeString2 = LocaleHelper.getDisplayName(locale2, true);
return localeString1.compareTo(localeString2);
});
localeDisplayName[0] = getString(R.string.language_system_default);
for (int i = 1; i < localeDisplayName.length; i++) {
Locale locale = availableLocales.get(i - 1);
localeDisplayName[i] = LocaleHelper.getDisplayName(locale, true);
String[] localeDisplayNames = new String[1 + availableLocales.size()];
localeDisplayNames[0] = getString(R.string.language_system_default);
for (int i = 1; i < localeDisplayNames.length; i++) {
localeDisplayNames[i] = LocaleHelper.getDisplayName(availableLocales.get(i - 1), true);
}
int currentLocaleIndex = 0;
String currentLocaleName = LocaleHelper.getLocale(LoginActivity.this);
if (!currentLocaleName.isEmpty()) {
Locale currentLocale = Locale.forLanguageTag(currentLocaleName);
String currentLocalizedString = LocaleHelper.getDisplayName(currentLocale, true);
currentLocaleIndex = Arrays.asList(localeDisplayName).indexOf(currentLocalizedString);
String currentLocaleTag = LocaleHelper.getPreferredLanguageTag(LoginActivity.this);
if (!currentLocaleTag.isEmpty()) {
Locale currentLocale = Locale.forLanguageTag(currentLocaleTag);
String currentLocaleName = LocaleHelper.getDisplayName(currentLocale, true);
currentLocaleIndex = Arrays.asList(localeDisplayNames).indexOf(currentLocaleName);
if (currentLocaleIndex < 0) currentLocaleIndex = 0;
}
AlertDialog.Builder builder = new AlertDialog.Builder(LoginActivity.this);
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(LoginActivity.this);
builder.setTitle(getString(R.string.menu_language));
builder.setSingleChoiceItems(localeDisplayName, currentLocaleIndex, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int i) {
dialog.dismiss();
builder.setSingleChoiceItems(localeDisplayNames, currentLocaleIndex, (dialog, i) -> {
dialog.dismiss();
LocaleHelper.setLocale(LoginActivity.this,
(i == 0) ? "" : availableLocales.get(i - 1).toLanguageTag());
startActivity(getIntent().addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK));
LocaleHelper.setAndSaveLocale(this,
(i == 0) ? "" : availableLocales.get(i - 1).toLanguageTag());
startActivity(getIntent().addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK));
});
builder.show();
}
public void onChangeTheme() {
final DayNightMode currentDayNightSetting = DayNightMode.getValue(AppCompatDelegate.getDefaultNightMode());
// selection will be empty if UNKNOWN
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(LoginActivity.this);
builder.setTitle(getString(R.string.menu_daynight));
String[] modeNames = getResources().getStringArray(R.array.daynight_themes);
builder.setSingleChoiceItems(modeNames, currentDayNightSetting.ordinal(), (dialog, i) -> {
dialog.dismiss();
final DayNightMode mode = DayNightMode.values()[i];
if (currentDayNightSetting != mode) {
NightmodeHelper.setAndSavePreferredNightmode(LoginActivity.this, mode);
LoginActivity.this.recreate();
}
});
builder.show();
@@ -1219,6 +1250,9 @@ public class LoginActivity extends BaseActivity
case R.id.action_language:
onChangeLocale();
return true;
case R.id.action_theme:
onChangeTheme();
return true;
case R.id.action_ledger_seed:
Fragment f = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
if (f instanceof GenerateFragment) {
@@ -1306,10 +1340,15 @@ public class LoginActivity extends BaseActivity
Helper.promptPassword(LoginActivity.this, walletName, false,
new Helper.PasswordAction() {
@Override
public void action(String walletName, String password, boolean fingerprintUsed) {
public void act(String walletName, String password, boolean fingerprintUsed) {
if (checkDevice(walletName, password))
startWallet(walletName, password, fingerprintUsed, streetmode);
}
@Override
public void fail(String walletName, String password, boolean fingerprintUsed) {
}
});
} else { // this cannot really happen as we prefilter choices
Toast.makeText(this, getString(R.string.bad_wallet), Toast.LENGTH_SHORT).show();

View File

@@ -19,11 +19,6 @@ package com.m2049r.xmrwallet;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.Fragment;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@@ -38,6 +33,12 @@ import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.m2049r.xmrwallet.data.NodeInfo;
import com.m2049r.xmrwallet.layout.NodeInfoAdapter;
import com.m2049r.xmrwallet.layout.WalletInfoAdapter;
@@ -63,6 +64,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
private List<WalletManager.WalletInfo> walletList = new ArrayList<>();
private List<WalletManager.WalletInfo> displayedList = new ArrayList<>();
private View tvGuntherSays;
private ImageView ivGunther;
private TextView tvNodeName;
private TextView tvNodeAddress;
@@ -143,6 +145,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
Timber.d("onCreateView");
View view = inflater.inflate(R.layout.fragment_login, container, false);
tvGuntherSays = view.findViewById(R.id.tvGuntherSays);
ivGunther = view.findViewById(R.id.ivGunther);
fabScreen = view.findViewById(R.id.fabScreen);
fab = view.findViewById(R.id.fab);
@@ -275,13 +278,15 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
if (displayedList.isEmpty()) {
fab.startAnimation(fab_pulse);
if (ivGunther.getDrawable() == null) {
ivGunther.setImageResource(R.drawable.gunther_desaturated);
ivGunther.setImageResource(R.drawable.ic_emptygunther);
tvGuntherSays.setVisibility(View.VISIBLE);
}
} else {
fab.clearAnimation();
if (ivGunther.getDrawable() != null) {
ivGunther.setImageDrawable(null);
}
tvGuntherSays.setVisibility(View.GONE);
}
// remove information of non-existent wallet

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2018-2020 EarlOfEgo, m2049r
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.m2049r.xmrwallet;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.m2049r.xmrwallet.onboarding.OnBoardingActivity;
import com.m2049r.xmrwallet.onboarding.OnBoardingManager;
public class MainActivity extends BaseActivity {
@Override
protected void onCreate(@Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (OnBoardingManager.shouldShowOnBoarding(getApplicationContext())) {
startActivity(new Intent(this, OnBoardingActivity.class));
} else {
startActivity(new Intent(this, LoginActivity.class));
}
finish();
}
}

View File

@@ -16,16 +16,19 @@
package com.m2049r.xmrwallet;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.TextInputLayout;
import android.support.v4.app.Fragment;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.RecyclerView;
import androidx.annotation.Nullable;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.textfield.TextInputLayout;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import androidx.recyclerview.widget.RecyclerView;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -445,7 +448,7 @@ public class NodeFragment extends Fragment
}
EditDialog(final NodeInfo nodeInfo) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity());
AlertDialog.Builder alertDialogBuilder = new MaterialAlertDialogBuilder(getActivity());
LayoutInflater li = LayoutInflater.from(alertDialogBuilder.getContext());
View promptsView = li.inflate(R.layout.prompt_editnode, null);
alertDialogBuilder.setView(promptsView);

View File

@@ -25,12 +25,6 @@ import android.net.Uri;
import android.nfc.NfcManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.TextInputLayout;
import android.support.v4.app.Fragment;
import android.support.v4.content.FileProvider;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.widget.ShareActionProvider;
import android.text.Editable;
import android.text.InputType;
import android.text.TextWatcher;
@@ -42,7 +36,6 @@ import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
@@ -50,6 +43,13 @@ import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.ShareActionProvider;
import androidx.core.content.FileProvider;
import androidx.core.view.MenuItemCompat;
import androidx.fragment.app.Fragment;
import com.google.android.material.textfield.TextInputLayout;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
@@ -82,10 +82,11 @@ public class ReceiveFragment extends Fragment {
private ExchangeView evAmount;
private TextView tvQrCode;
private ImageView ivQrCode;
private View cvQrCode;
private ImageView ivQrCodeFull;
private EditText etDummy;
private ImageButton bCopyAddress;
private Button bSubaddress;
private ImageButton bSubaddress;
private Wallet wallet = null;
private boolean isMyWallet = false;
@@ -109,6 +110,7 @@ public class ReceiveFragment extends Fragment {
tvAddress = view.findViewById(R.id.tvAddress);
etNotes = view.findViewById(R.id.etNotes);
evAmount = view.findViewById(R.id.evAmount);
cvQrCode = view.findViewById(R.id.cvQrCode);
ivQrCode = view.findViewById(R.id.qrCode);
tvQrCode = view.findViewById(R.id.tvQrCode);
ivQrCodeFull = view.findViewById(R.id.qrCodeFull);
@@ -118,13 +120,9 @@ public class ReceiveFragment extends Fragment {
etDummy.setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
bCopyAddress.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
copyAddress();
}
});
bCopyAddress.setOnClickListener(v -> copyAddress());
enableCopyAddress(false);
enableSubaddressButton(false);
evAmount.setOnNewAmountListener(new ExchangeView.OnNewAmountListener() {
@Override
@@ -190,7 +188,7 @@ public class ReceiveFragment extends Fragment {
}
});
ivQrCode.setOnClickListener(new View.OnClickListener() {
cvQrCode.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Helper.hideKeyboard(getActivity());
@@ -315,13 +313,8 @@ public class ReceiveFragment extends Fragment {
return null;
}
void enableSubaddressButton(boolean enable) {
private void enableSubaddressButton(boolean enable) {
bSubaddress.setEnabled(enable);
if (enable) {
bSubaddress.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.ic_settings_orange_24dp, 0, 0);
} else {
bSubaddress.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.ic_settings_gray_24dp, 0, 0);
}
}
void copyAddress() {
@@ -371,16 +364,13 @@ public class ReceiveFragment extends Fragment {
listenerCallback.setSubtitle(wallet.getAccountLabel());
tvAddress.setText(wallet.getAddress());
enableCopyAddress(true);
enableSubaddressButton(true);
hideProgress();
generateQr();
}
private void enableCopyAddress(boolean enable) {
bCopyAddress.setClickable(enable);
if (enable)
bCopyAddress.setImageResource(R.drawable.ic_content_copy_black_24dp);
else
bCopyAddress.setImageResource(R.drawable.ic_content_nocopy_black_24dp);
bCopyAddress.setEnabled(enable);
}
private void loadAndShow(String walletPath, String password) {

View File

@@ -19,7 +19,7 @@ package com.m2049r.xmrwallet;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

View File

@@ -17,13 +17,18 @@
package com.m2049r.xmrwallet;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.m2049r.xmrwallet.util.Helper;
import com.m2049r.xmrwallet.util.LocaleHelper;
import java.util.Locale;
import static android.view.WindowManager.LayoutParams;
public abstract class SecureActivity extends AppCompatActivity {
@@ -37,7 +42,36 @@ public abstract class SecureActivity extends AppCompatActivity {
}
@Override
protected void attachBaseContext(Context context) {
super.attachBaseContext(LocaleHelper.setLocale(context, LocaleHelper.getLocale(context)));
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(newBase);
applyOverrideConfiguration(new Configuration());
}
@Override
public void applyOverrideConfiguration(Configuration newConfig) {
super.applyOverrideConfiguration(updateConfigurationIfSupported(newConfig));
}
private Configuration updateConfigurationIfSupported(Configuration config) {
// Configuration.getLocales is added after 24 and Configuration.locale is deprecated in 24
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
if (!config.getLocales().isEmpty()) {
return config;
}
} else {
if (config.locale != null) {
return config;
}
}
Locale locale = LocaleHelper.getPreferredLocale(this);
if (locale != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
config.setLocale(locale);
} else {
config.locale = locale;
}
}
return config;
}
}

View File

@@ -19,24 +19,24 @@ package com.m2049r.xmrwallet;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.text.InputType;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import com.m2049r.xmrwallet.data.UserNotes;
import com.m2049r.xmrwallet.model.TransactionInfo;
import com.m2049r.xmrwallet.model.Transfer;
import com.m2049r.xmrwallet.model.Wallet;
import com.m2049r.xmrwallet.util.Helper;
import com.m2049r.xmrwallet.data.UserNotes;
import com.m2049r.xmrwallet.widget.Toolbar;
import java.text.SimpleDateFormat;
@@ -242,9 +242,9 @@ public class TxFragment extends Fragment {
} else if (info.isPending) {
setTxColour(ContextCompat.getColor(getContext(), R.color.tx_pending));
} else if (info.direction == TransactionInfo.Direction.Direction_In) {
setTxColour(ContextCompat.getColor(getContext(), R.color.tx_green));
setTxColour(ContextCompat.getColor(getContext(), R.color.tx_plus));
} else {
setTxColour(ContextCompat.getColor(getContext(), R.color.tx_red));
setTxColour(ContextCompat.getColor(getContext(), R.color.tx_minus));
}
Set<String> destinations = new HashSet<>();
StringBuffer sb = new StringBuffer();

View File

@@ -16,7 +16,6 @@
package com.m2049r.xmrwallet;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
@@ -27,14 +26,6 @@ import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -45,6 +36,17 @@ import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AlertDialog;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.navigation.NavigationView;
import com.m2049r.xmrwallet.data.BarcodeData;
import com.m2049r.xmrwallet.data.TxData;
import com.m2049r.xmrwallet.data.UserNotes;
@@ -58,6 +60,7 @@ import com.m2049r.xmrwallet.model.TransactionInfo;
import com.m2049r.xmrwallet.model.Wallet;
import com.m2049r.xmrwallet.model.WalletManager;
import com.m2049r.xmrwallet.service.WalletService;
import com.m2049r.xmrwallet.util.ColorHelper;
import com.m2049r.xmrwallet.util.Helper;
import com.m2049r.xmrwallet.util.MoneroThreadPoolExecutor;
import com.m2049r.xmrwallet.widget.Toolbar;
@@ -88,7 +91,6 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
private ActionBarDrawerToggle drawerToggle;
private Toolbar toolbar;
private boolean needVerifyIdentity;
private boolean requestStreetMode = false;
private String password;
@@ -142,7 +144,6 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
private void enableStreetMode(boolean enable) {
if (enable) {
needVerifyIdentity = true;
streetMode = getWallet().getDaemonBlockChainHeight();
} else {
streetMode = 0;
@@ -151,11 +152,9 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
getSupportFragmentManager().findFragmentByTag(WalletFragment.class.getName());
if (walletFragment != null) walletFragment.resetDismissedTransactions();
forceUpdate();
runOnUiThread(new Runnable() {
@Override
public void run() {
runOnUiThread(() -> {
if (getWallet() != null)
updateAccountsBalance();
}
});
}
@@ -200,7 +199,6 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
if (extras != null) {
acquireWakeLock();
String walletId = extras.getString(REQUEST_ID);
needVerifyIdentity = extras.getBoolean(REQUEST_FINGERPRINT_USED);
// we can set the streetmode height AFTER opening the wallet
requestStreetMode = extras.getBoolean(REQUEST_STREETMODE);
password = extras.getString(REQUEST_PW);
@@ -217,6 +215,20 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
releaseWakeLock();
}
private void onWalletRescan() {
try {
final WalletFragment walletFragment = (WalletFragment)
getSupportFragmentManager().findFragmentByTag(WalletFragment.class.getName());
getWallet().rescanBlockchainAsync();
synced = false;
walletFragment.unsync();
invalidateOptionsMenu();
} catch (ClassCastException ex) {
Timber.d(ex.getLocalizedMessage());
// keep calm and carry on
}
}
@Override
protected void onStop() {
Timber.d("onStop()");
@@ -243,7 +255,7 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem renameItem = menu.findItem(R.id.action_rename);
if (renameItem != null)
renameItem.setVisible(hasWallet() && getWallet().isSynchronized());
renameItem.setEnabled(hasWallet() && getWallet().isSynchronized());
MenuItem streetmodeItem = menu.findItem(R.id.action_streetmode);
if (streetmodeItem != null)
if (isStreetMode()) {
@@ -251,12 +263,18 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
} else {
streetmodeItem.setIcon(R.drawable.gunther_24dp);
}
final MenuItem rescanItem = menu.findItem(R.id.action_rescan);
if (rescanItem != null)
rescanItem.setEnabled(isSynced());
return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_rescan:
onWalletRescan();
return true;
case R.id.action_info:
onWalletDetails();
return true;
@@ -297,11 +315,6 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
}
private void updateStreetMode() {
if (isStreetMode()) {
toolbar.setBackgroundResource(R.drawable.backgound_toolbar_streetmode);
} else {
showNet();
}
invalidateOptionsMenu();
}
@@ -313,7 +326,7 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
private void onDisableStreetMode() {
Helper.promptPassword(WalletActivity.this, getWallet().getName(), false, new Helper.PasswordAction() {
@Override
public void action(String walletName, String password, boolean fingerprintUsed) {
public void act(String walletName, String password, boolean fingerprintUsed) {
runOnUiThread(new Runnable() {
@Override
public void run() {
@@ -322,6 +335,10 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
}
});
}
@Override
public void fail(String walletName, String password, boolean fingerprintUsed) {
}
});
}
@@ -407,10 +424,10 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
toolbar.setBackgroundResource(R.drawable.backgound_toolbar_mainnet);
break;
case NetworkType_Testnet:
toolbar.setBackgroundResource(R.color.colorPrimaryDark);
toolbar.setBackgroundResource(ColorHelper.getThemedResourceId(this, R.attr.colorPrimaryDark));
break;
case NetworkType_Stagenet:
toolbar.setBackgroundResource(R.color.colorPrimaryDark);
toolbar.setBackgroundResource(ColorHelper.getThemedResourceId(this, R.attr.colorPrimaryDark));
break;
default:
throw new IllegalStateException("Unsupported Network: " + WalletManager.getInstance().getNetworkType());
@@ -556,10 +573,9 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
@Override
public boolean onRefreshed(final Wallet wallet, final boolean full) {
Timber.d("onRefreshed()");
runOnUiThread(new Runnable() {
public void run() {
runOnUiThread(() -> {
if (getWallet() != null)
updateAccountsBalance();
}
});
if (numAccounts != wallet.getNumAccounts()) {
numAccounts = wallet.getNumAccounts();
@@ -649,7 +665,7 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
haveWallet = true;
invalidateOptionsMenu();
enableStreetMode(requestStreetMode);
if (requestStreetMode) onEnableStreetMode();
final WalletFragment walletFragment = (WalletFragment)
getSupportFragmentManager().findFragmentById(R.id.fragment_container);
@@ -835,17 +851,16 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
final Bundle extras = new Bundle();
extras.putString(GenerateReviewFragment.REQUEST_TYPE, GenerateReviewFragment.VIEW_TYPE_WALLET);
if (needVerifyIdentity) {
Helper.promptPassword(WalletActivity.this, getWallet().getName(), true, new Helper.PasswordAction() {
@Override
public void action(String walletName, String password, boolean fingerprintUsed) {
replaceFragment(new GenerateReviewFragment(), null, extras);
needVerifyIdentity = false;
}
});
} else {
replaceFragment(new GenerateReviewFragment(), null, extras);
}
Helper.promptPassword(WalletActivity.this, getWallet().getName(), true, new Helper.PasswordAction() {
@Override
public void act(String walletName, String password, boolean fingerprintUsed) {
replaceFragment(new GenerateReviewFragment(), null, extras);
}
@Override
public void fail(String walletName, String password, boolean fingerprintUsed) {
}
});
break;
case DialogInterface.BUTTON_NEGATIVE:
@@ -855,7 +870,7 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(this);
builder.setMessage(getString(R.string.details_alert_message))
.setPositiveButton(getString(R.string.details_alert_yes), dialogClickListener)
.setNegativeButton(getString(R.string.details_alert_no), dialogClickListener)
@@ -983,12 +998,6 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
return getWallet().getUnlockedBalance();
}
@Override
public boolean verifyWalletPassword(String password) {
String walletPassword = Helper.getWalletPassword(getApplicationContext(), getWalletName(), password);
return walletPassword != null;
}
@Override
public void onBackPressed() {
if (drawer.isDrawerOpen(GravityCompat.START)) {
@@ -1082,7 +1091,7 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
final LayoutInflater li = LayoutInflater.from(this);
final View promptsView = li.inflate(R.layout.prompt_rename, null);
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
final AlertDialog.Builder alertDialogBuilder = new MaterialAlertDialogBuilder(this);
alertDialogBuilder.setView(promptsView);
final EditText etRename = promptsView.findViewById(R.id.etRename);

View File

@@ -17,12 +17,10 @@
package com.m2049r.xmrwallet;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@@ -38,6 +36,11 @@ import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView;
import com.github.brnunes.swipeablerecyclerview.SwipeableRecyclerViewTouchListener;
import com.m2049r.xmrwallet.layout.TransactionInfoAdapter;
import com.m2049r.xmrwallet.model.TransactionInfo;
@@ -70,6 +73,8 @@ public class WalletFragment extends Fragment
private ProgressBar pbProgress;
private Button bReceive;
private Button bSend;
private ImageView ivStreetGunther;
private Drawable streetGunther = null;
private Spinner sCurrency;
@@ -97,11 +102,12 @@ public class WalletFragment extends Fragment
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_wallet, container, false);
ivStreetGunther = view.findViewById(R.id.ivStreetGunther);
tvStreetView = view.findViewById(R.id.tvStreetView);
llBalance = view.findViewById(R.id.llBalance);
flExchange = view.findViewById(R.id.flExchange);
((ProgressBar) view.findViewById(R.id.pbExchange)).getIndeterminateDrawable().
setColorFilter(getResources().getColor(R.color.trafficGray),
setColorFilter(getResources().getColor(R.color.progress_circle),
android.graphics.PorterDuff.Mode.MULTIPLY);
tvProgress = view.findViewById(R.id.tvProgress);
@@ -199,13 +205,15 @@ public class WalletFragment extends Fragment
void showBalance(String balance) {
tvBalance.setText(balance);
if (!activityCallback.isStreetMode()) {
final boolean streetMode = activityCallback.isStreetMode();
if (!streetMode) {
llBalance.setVisibility(View.VISIBLE);
tvStreetView.setVisibility(View.INVISIBLE);
} else {
llBalance.setVisibility(View.INVISIBLE);
tvStreetView.setVisibility(View.VISIBLE);
}
setStreetModeBackground(streetMode);
}
void showUnconfirmed(double unconfirmedAmount) {
@@ -356,6 +364,15 @@ public class WalletFragment extends Fragment
if (isVisible()) enableAccountsList(true); //otherwise it is enabled in onResume()
}
public void unsync() {
if (!activityCallback.isWatchOnly()) {
bSend.setVisibility(View.INVISIBLE);
bSend.setEnabled(false);
}
if (isVisible()) enableAccountsList(false); //otherwise it is enabled in onResume()
firstBlock = 0;
}
boolean walletLoaded = false;
public void onLoaded() {
@@ -528,4 +545,13 @@ public class WalletFragment extends Fragment
}
}
public void setStreetModeBackground(boolean enable) {
//TODO figure out why gunther disappears on return from send although he is still set
if (enable) {
if (streetGunther == null)
streetGunther = ContextCompat.getDrawable(getContext(), R.drawable.ic_gunther_streetmode);
ivStreetGunther.setImageDrawable(streetGunther);
} else
ivStreetGunther.setImageDrawable(null);
}
}

View File

@@ -20,9 +20,12 @@ package com.m2049r.xmrwallet;
import android.app.Application;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Build;
import com.m2049r.xmrwallet.model.NetworkType;
import com.m2049r.xmrwallet.util.DayNightMode;
import com.m2049r.xmrwallet.util.LocaleHelper;
import com.m2049r.xmrwallet.util.NightmodeHelper;
import timber.log.Timber;
@@ -34,18 +37,23 @@ public class XmrWalletApplication extends Application {
if (BuildConfig.DEBUG) {
Timber.plant(new Timber.DebugTree());
}
NightmodeHelper.setPreferredNightmode(this);
}
@Override
protected void attachBaseContext(Context context) {
super.attachBaseContext(LocaleHelper.setLocale(context, LocaleHelper.getLocale(context)));
super.attachBaseContext(LocaleHelper.setPreferredLocale(context));
}
@Override
public void onConfigurationChanged(Configuration configuration) {
super.onConfigurationChanged(configuration);
LocaleHelper.updateSystemDefaultLocale(configuration.locale);
LocaleHelper.setLocale(XmrWalletApplication.this, LocaleHelper.getLocale(XmrWalletApplication.this));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
LocaleHelper.updateSystemDefaultLocale(configuration.getLocales().get(0));
} else {
LocaleHelper.updateSystemDefaultLocale(configuration.locale);
}
LocaleHelper.setPreferredLocale(this);
}
static public NetworkType getNetworkType() {
@@ -54,7 +62,7 @@ public class XmrWalletApplication extends Application {
return NetworkType.NetworkType_Mainnet;
case "stagenet":
return NetworkType.NetworkType_Stagenet;
case "testnet":
case "devnet": // flavors cannot start with "test"
return NetworkType.NetworkType_Testnet;
default:
throw new IllegalStateException("unknown net flavor " + BuildConfig.FLAVOR_net);

View File

@@ -16,26 +16,25 @@
package com.m2049r.xmrwallet.dialog;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.m2049r.xmrwallet.BuildConfig;
import com.m2049r.xmrwallet.R;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import timber.log.Timber;
@@ -63,15 +62,15 @@ public class AboutFragment extends DialogFragment {
((TextView) view.findViewById(R.id.tvHelp)).setText(Html.fromHtml(getLicencesHtml()));
((TextView) view.findViewById(R.id.tvVersion)).setText(getString(R.string.about_version, BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE));
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(view);
builder.setNegativeButton(R.string.about_close,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getActivity())
.setView(view)
.setNegativeButton(R.string.about_close,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
return builder.create();
}

View File

@@ -16,19 +16,20 @@
package com.m2049r.xmrwallet.dialog;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.m2049r.xmrwallet.R;
public class CreditsFragment extends DialogFragment {
@@ -54,16 +55,15 @@ public class CreditsFragment extends DialogFragment {
((TextView) view.findViewById(R.id.tvCredits)).setText(Html.fromHtml(getString(R.string.credits_text)));
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(view);
builder.setNegativeButton(R.string.about_close,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getActivity())
.setView(view)
.setNegativeButton(R.string.about_close,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
return builder.create();
}
}

View File

@@ -16,19 +16,20 @@
package com.m2049r.xmrwallet.dialog;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.m2049r.xmrwallet.R;
public class HelpFragment extends DialogFragment {
@@ -65,15 +66,15 @@ public class HelpFragment extends DialogFragment {
if (helpId > 0)
((TextView) view.findViewById(R.id.tvHelp)).setText(Html.fromHtml(getString(helpId)));
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(view);
builder.setNegativeButton(R.string.help_ok,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getActivity())
.setView(view)
.setNegativeButton(R.string.help_ok,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
return builder.create();
}
}

View File

@@ -16,19 +16,20 @@
package com.m2049r.xmrwallet.dialog;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.m2049r.xmrwallet.R;
public class PrivacyFragment extends DialogFragment {
@@ -54,15 +55,15 @@ public class PrivacyFragment extends DialogFragment {
((TextView) view.findViewById(R.id.tvCredits)).setText(Html.fromHtml(getString(R.string.privacy_policy)));
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(view);
builder.setNegativeButton(R.string.about_close,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getActivity())
.setView(view)
.setNegativeButton(R.string.about_close,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
return builder.create();
}
}

View File

@@ -17,7 +17,6 @@ package com.m2049r.xmrwallet.dialog;
* limitations under the License.
*/
import android.app.AlertDialog;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
@@ -26,6 +25,8 @@ import android.view.WindowManager;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
import com.m2049r.xmrwallet.BuildConfig;
import com.m2049r.xmrwallet.R;
import com.m2049r.xmrwallet.util.Helper;

View File

@@ -19,8 +19,6 @@ package com.m2049r.xmrwallet.fragment.send;
import android.content.Context;
import android.nfc.NfcManager;
import android.os.Bundle;
import android.support.design.widget.TextInputLayout;
import android.support.v7.widget.CardView;
import android.text.Editable;
import android.text.Html;
import android.text.InputType;
@@ -36,6 +34,7 @@ import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.material.textfield.TextInputLayout;
import com.m2049r.xmrwallet.R;
import com.m2049r.xmrwallet.data.BarcodeData;
import com.m2049r.xmrwallet.data.TxData;
@@ -86,7 +85,7 @@ public class SendAddressWizardFragment extends SendWizardFragment {
private EditText etDummy;
private TextInputLayout etAddress;
private TextInputLayout etNotes;
private CardView cvScan;
private View cvScan;
private View tvPaymentIdIntegrated;
private TextView tvXmrTo;
private View llXmrTo;

View File

@@ -148,12 +148,9 @@ public class SendAmountWizardFragment extends SendWizardFragment {
tvFunds.setText(getString(R.string.send_available,
getString(R.string.unknown_amount)));
}
// getNativeAmount is null if exchange is in progress
if ((etAmount.getNativeAmount() != null) && etAmount.getNativeAmount().isEmpty()) {
final BarcodeData data = sendListener.popBarcodeData();
if ((data != null) && (data.amount != null)) {
etAmount.setAmount(data.amount);
}
final BarcodeData data = sendListener.popBarcodeData();
if ((data != null) && (data.amount != null)) {
etAmount.setAmount(data.amount);
}
}

View File

@@ -16,24 +16,23 @@
package com.m2049r.xmrwallet.fragment.send;
import android.app.Activity;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.support.design.widget.TextInputLayout;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.textfield.TextInputLayout;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.m2049r.xmrwallet.BuildConfig;
import androidx.appcompat.app.AlertDialog;
import com.m2049r.xmrwallet.R;
import com.m2049r.xmrwallet.data.TxData;
import com.m2049r.xmrwallet.data.TxDataBtc;
@@ -213,7 +212,7 @@ public class SendBtcConfirmWizardFragment extends SendWizardFragment implements
((TxDataBtc) sendListener.getTxData()).setXmrtoUuid(xmrtoStatus.getUuid());
// TODO make method in TxDataBtc to set both of the above in one go
sendListener.commitTransaction();
pbProgressSend.setVisibility(View.VISIBLE);
getActivity().runOnUiThread(() -> pbProgressSend.setVisibility(View.VISIBLE));
}
@Override
@@ -346,103 +345,18 @@ public class SendBtcConfirmWizardFragment extends SendWizardFragment implements
}
public void preSend() {
final Activity activity = getActivity();
View promptsView = getLayoutInflater().inflate(R.layout.prompt_password, null);
android.app.AlertDialog.Builder alertDialogBuilder = new android.app.AlertDialog.Builder(activity);
alertDialogBuilder.setView(promptsView);
final TextInputLayout etPassword = promptsView.findViewById(R.id.etPassword);
etPassword.setHint(getString(R.string.prompt_send_password));
etPassword.getEditText().addTextChangedListener(new TextWatcher() {
Helper.promptPassword(getContext(), getActivityCallback().getWalletName(), false, new Helper.PasswordAction() {
@Override
public void afterTextChanged(Editable s) {
if (etPassword.getError() != null) {
etPassword.setError(null);
}
public void act(String walletName, String password, boolean fingerprintUsed) {
send();
}
@Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
}
});
alertDialogBuilder
.setCancelable(false)
.setPositiveButton(getString(R.string.label_ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
String pass = etPassword.getEditText().getText().toString();
if (getActivityCallback().verifyWalletPassword(pass)) {
dialog.dismiss();
Helper.hideKeyboardAlways(activity);
send();
} else {
etPassword.setError(getString(R.string.bad_password));
}
}
})
.setNegativeButton(getString(R.string.label_cancel),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Helper.hideKeyboardAlways(activity);
dialog.cancel();
bSend.setEnabled(sendCountdown > 0); // allow to try again
}
});
final android.app.AlertDialog passwordDialog = alertDialogBuilder.create();
passwordDialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
Button button = ((android.app.AlertDialog) dialog).getButton(android.app.AlertDialog.BUTTON_POSITIVE);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String pass = etPassword.getEditText().getText().toString();
if (getActivityCallback().verifyWalletPassword(pass)) {
Helper.hideKeyboardAlways(activity);
passwordDialog.dismiss();
send();
} else {
etPassword.setError(getString(R.string.bad_password));
}
}
public void fail(String walletName, String password, boolean fingerprintUsed) {
getActivity().runOnUiThread(() -> {
bSend.setEnabled(sendCountdown > 0); // allow to try again
});
}
});
Helper.showKeyboard(passwordDialog);
// accept keyboard "ok"
etPassword.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() {
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN))
|| (actionId == EditorInfo.IME_ACTION_DONE)) {
String pass = etPassword.getEditText().getText().toString();
if (getActivityCallback().verifyWalletPassword(pass)) {
Helper.hideKeyboardAlways(activity);
passwordDialog.dismiss();
send();
} else {
etPassword.setError(getString(R.string.bad_password));
}
return true;
}
return false;
}
});
if (Helper.preventScreenshot()) {
passwordDialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
}
passwordDialog.show();
}
// creates a pending transaction and calls us back with transactionCreated()
@@ -457,8 +371,8 @@ public class SendBtcConfirmWizardFragment extends SendWizardFragment implements
}
showProgress(3, getString(R.string.label_send_progress_create_tx));
TxData txData = sendListener.getTxData();
txData.setDestinationAddress(xmrtoStatus.getXmrReceivingSubaddress());
txData.setAmount(Wallet.getAmountFromDouble(xmrtoStatus.getXmrAmountTotal()));
txData.setDestinationAddress(xmrtoStatus.getReceivingSubaddress());
txData.setAmount(Wallet.getAmountFromDouble(xmrtoStatus.getIncomingAmountTotal()));
getActivityCallback().onPrepareSend(xmrtoStatus.getUuid(), txData);
}
@@ -572,22 +486,22 @@ public class SendBtcConfirmWizardFragment extends SendWizardFragment implements
NumberFormat df = NumberFormat.getInstance(Locale.US);
df.setMaximumFractionDigits(12);
String btcAmount = df.format(status.getBtcAmount());
String xmrAmountTotal = df.format(status.getXmrAmountTotal());
String xmrAmountTotal = df.format(status.getIncomingAmountTotal());
tvTxBtcAmount.setText(getString(R.string.text_send_btc_amount, btcAmount, xmrAmountTotal));
String xmrPriceBtc = df.format(status.getXmrPriceBtc());
String xmrPriceBtc = df.format(status.getIncomingPriceBtc());
tvTxBtcRate.setText(getString(R.string.text_send_btc_rate, xmrPriceBtc));
double calcRate = status.getBtcAmount() / status.getXmrPriceBtc();
Timber.i("Rates: %f / %f", calcRate, status.getXmrPriceBtc());
double calcRate = status.getBtcAmount() / status.getIncomingPriceBtc();
Timber.d("Rates: %f / %f", calcRate, status.getIncomingPriceBtc());
tvTxBtcAddress.setText(status.getBtcDestAddress()); // TODO test if this is different?
Timber.i("Expires @ %s, in %s seconds", status.getExpiresAt().toString(), status.getSecondsTillTimeout());
Timber.d("Expires @ %s, in %s seconds", status.getExpiresAt().toString(), status.getSecondsTillTimeout());
Timber.i("Status = %s", status.getState().toString());
Timber.d("Status = %s", status.getState().toString());
tvTxXmrToKey.setText(status.getUuid());
Timber.d("AmountRemaining=%f, XmrAmountTotal=%f", status.getXmrAmountRemaining(), status.getXmrAmountTotal());
Timber.d("AmountRemaining=%f, XmrAmountTotal=%f", status.getRemainingAmountIncoming(), status.getIncomingAmountTotal());
hideProgress();
startSendTimer();
prepareSend();

View File

@@ -80,12 +80,10 @@ public class SendBtcSuccessWizardFragment extends SendWizardFragment {
R.layout.fragment_send_btc_success, container, false);
bCopyTxId = view.findViewById(R.id.bCopyTxId);
bCopyTxId.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Helper.clipBoardCopy(getActivity(), getString(R.string.label_send_txid), tvTxId.getText().toString());
Toast.makeText(getActivity(), getString(R.string.message_copy_txid), Toast.LENGTH_SHORT).show();
}
bCopyTxId.setEnabled(false);
bCopyTxId.setOnClickListener(v -> {
Helper.clipBoardCopy(getActivity(), getString(R.string.label_send_txid), tvTxId.getText().toString());
Toast.makeText(getActivity(), getString(R.string.message_copy_txid), Toast.LENGTH_SHORT).show();
});
tvXmrToAmount = view.findViewById(R.id.tvXmrToAmount);
@@ -143,7 +141,6 @@ public class SendBtcSuccessWizardFragment extends SendWizardFragment {
if (committedTx != null) {
tvTxId.setText(committedTx.txId);
bCopyTxId.setEnabled(true);
bCopyTxId.setImageResource(R.drawable.ic_content_copy_black_24dp);
tvTxAmount.setText(getString(R.string.send_amount, Helper.getDisplayAmount(committedTx.amount)));
tvTxFee.setText(getString(R.string.send_fee, Helper.getDisplayAmount(committedTx.fee)));
if (btcData != null) {

View File

@@ -16,29 +16,25 @@
package com.m2049r.xmrwallet.fragment.send;
import android.app.Activity;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.design.widget.TextInputLayout;
import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.TextView;
import com.m2049r.xmrwallet.BuildConfig;
import androidx.appcompat.app.AlertDialog;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.textfield.TextInputLayout;
import com.m2049r.xmrwallet.R;
import com.m2049r.xmrwallet.data.TxData;
import com.m2049r.xmrwallet.data.UserNotes;
import com.m2049r.xmrwallet.model.PendingTransaction;
import com.m2049r.xmrwallet.model.Wallet;
import com.m2049r.xmrwallet.util.Helper;
import com.m2049r.xmrwallet.data.UserNotes;
import timber.log.Timber;
@@ -141,7 +137,7 @@ public class SendConfirmWizardFragment extends SendWizardFragment implements Sen
void send() {
sendListener.commitTransaction();
pbProgressSend.setVisibility(View.VISIBLE);
getActivity().runOnUiThread(() -> pbProgressSend.setVisibility(View.VISIBLE));
}
@Override
@@ -157,7 +153,7 @@ public class SendConfirmWizardFragment extends SendWizardFragment implements Sen
}
private void showAlert(String title, String message) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(getActivity());
builder.setCancelable(true).
setTitle(title).
setMessage(message).
@@ -225,103 +221,18 @@ public class SendConfirmWizardFragment extends SendWizardFragment implements Sen
}
public void preSend() {
final Activity activity = getActivity();
View promptsView = getLayoutInflater().inflate(R.layout.prompt_password, null);
android.app.AlertDialog.Builder alertDialogBuilder = new android.app.AlertDialog.Builder(activity);
alertDialogBuilder.setView(promptsView);
final TextInputLayout etPassword = promptsView.findViewById(R.id.etPassword);
etPassword.setHint(getString(R.string.prompt_send_password));
etPassword.getEditText().addTextChangedListener(new TextWatcher() {
Helper.promptPassword(getContext(), getActivityCallback().getWalletName(), false, new Helper.PasswordAction() {
@Override
public void afterTextChanged(Editable s) {
if (etPassword.getError() != null) {
etPassword.setError(null);
}
public void act(String walletName, String password, boolean fingerprintUsed) {
send();
}
@Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
}
});
alertDialogBuilder
.setCancelable(false)
.setPositiveButton(getString(R.string.label_ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
String pass = etPassword.getEditText().getText().toString();
if (getActivityCallback().verifyWalletPassword(pass)) {
dialog.dismiss();
Helper.hideKeyboardAlways(activity);
send();
} else {
etPassword.setError(getString(R.string.bad_password));
}
}
})
.setNegativeButton(getString(R.string.label_cancel),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Helper.hideKeyboardAlways(activity);
dialog.cancel();
bSend.setEnabled(true); // allow to try again
}
});
final android.app.AlertDialog passwordDialog = alertDialogBuilder.create();
passwordDialog.setOnShowListener(new DialogInterface.OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
Button button = ((android.app.AlertDialog) dialog).getButton(android.app.AlertDialog.BUTTON_POSITIVE);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String pass = etPassword.getEditText().getText().toString();
if (getActivityCallback().verifyWalletPassword(pass)) {
Helper.hideKeyboardAlways(activity);
passwordDialog.dismiss();
send();
} else {
etPassword.setError(getString(R.string.bad_password));
}
}
public void fail(String walletName, String password, boolean fingerprintUsed) {
getActivity().runOnUiThread(() -> {
bSend.setEnabled(true); // allow to try again
});
}
});
Helper.showKeyboard(passwordDialog);
// accept keyboard "ok"
etPassword.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() {
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN))
|| (actionId == EditorInfo.IME_ACTION_DONE)) {
String pass = etPassword.getEditText().getText().toString();
if (getActivityCallback().verifyWalletPassword(pass)) {
Helper.hideKeyboardAlways(activity);
passwordDialog.dismiss();
send();
} else {
etPassword.setError(getString(R.string.bad_password));
}
return true;
}
return false;
}
});
if (Helper.preventScreenshot()) {
passwordDialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
}
passwordDialog.show();
}
// creates a pending transaction and calls us back with transactionCreated()

View File

@@ -18,13 +18,7 @@ package com.m2049r.xmrwallet.fragment.send;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.text.InputType;
import android.util.SparseArray;
import android.view.LayoutInflater;
@@ -35,6 +29,12 @@ import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;
import com.m2049r.xmrwallet.OnBackPressedListener;
import com.m2049r.xmrwallet.OnUriScannedListener;
import com.m2049r.xmrwallet.R;
@@ -75,7 +75,7 @@ public class SendFragment extends Fragment
void onPrepareSend(String tag, TxData data);
boolean verifyWalletPassword(String password);
String getWalletName();
void onSend(UserNotes notes);
@@ -93,8 +93,6 @@ public class SendFragment extends Fragment
}
private EditText etDummy;
private Drawable arrowPrev;
private Drawable arrowNext;
private View llNavBar;
private DotBar dotBar;
@@ -125,8 +123,6 @@ public class SendFragment extends Fragment
dotBar = view.findViewById(R.id.dotBar);
bPrev = view.findViewById(R.id.bPrev);
bNext = view.findViewById(R.id.bNext);
arrowPrev = getResources().getDrawable(R.drawable.ic_navigate_prev_white_24dp);
arrowNext = getResources().getDrawable(R.drawable.ic_navigate_next_white_24dp);
ViewGroup llNotice = view.findViewById(R.id.llNotice);
Notice.showAll(llNotice, ".*_send");
@@ -214,16 +210,16 @@ public class SendFragment extends Fragment
CharSequence nextLabel = pagerAdapter.getPageTitle(position + 1);
bNext.setText(nextLabel);
if (nextLabel != null) {
bNext.setCompoundDrawablesWithIntrinsicBounds(null, null, arrowNext, null);
bNext.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_navigate_next_white_24dp, 0);
} else {
bNext.setCompoundDrawables(null, null, null, null);
bNext.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
}
CharSequence prevLabel = pagerAdapter.getPageTitle(position - 1);
bPrev.setText(prevLabel);
if (prevLabel != null) {
bPrev.setCompoundDrawablesWithIntrinsicBounds(arrowPrev, null, null, null);
bPrev.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_navigate_prev_white_24dp, 0, 0, 0);
} else {
bPrev.setCompoundDrawables(null, null, null, null);
bPrev.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
}
}

View File

@@ -76,12 +76,10 @@ public class SendSuccessWizardFragment extends SendWizardFragment {
R.layout.fragment_send_success, container, false);
bCopyTxId = view.findViewById(R.id.bCopyTxId);
bCopyTxId.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Helper.clipBoardCopy(getActivity(), getString(R.string.label_send_txid), tvTxId.getText().toString());
Toast.makeText(getActivity(), getString(R.string.message_copy_txid), Toast.LENGTH_SHORT).show();
}
bCopyTxId.setEnabled(false);
bCopyTxId.setOnClickListener(v -> {
Helper.clipBoardCopy(getActivity(), getString(R.string.label_send_txid), tvTxId.getText().toString());
Toast.makeText(getActivity(), getString(R.string.message_copy_txid), Toast.LENGTH_SHORT).show();
});
tvTxId = view.findViewById(R.id.tvTxId);
@@ -116,7 +114,6 @@ public class SendSuccessWizardFragment extends SendWizardFragment {
if (committedTx != null) {
tvTxId.setText(committedTx.txId);
bCopyTxId.setEnabled(true);
bCopyTxId.setImageResource(R.drawable.ic_content_copy_black_24dp);
if (sendListener.getActivityCallback().isStreetMode()
&& (sendListener.getTxData().getAmount() == Wallet.SWEEP_ALL)) {

View File

@@ -16,7 +16,7 @@
package com.m2049r.xmrwallet.fragment.send;
import android.support.v4.app.Fragment;
import androidx.fragment.app.Fragment;
import com.m2049r.xmrwallet.layout.SpendViewPager;

View File

@@ -17,8 +17,8 @@
package com.m2049r.xmrwallet.layout;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -130,9 +130,9 @@ public class NodeInfoAdapter extends RecyclerView.Adapter<NodeInfoAdapter.ViewHo
private void showStar() {
if (nodeItem.isFavourite()) {
ibBookmark.setImageResource(R.drawable.ic_bookmark_24dp);
ibBookmark.setImageResource(R.drawable.ic_favorite_24dp);
} else {
ibBookmark.setImageResource(R.drawable.ic_bookmark_border_24dp);
ibBookmark.setImageResource(R.drawable.ic_favorite_border_24dp);
}
}
@@ -170,16 +170,16 @@ public class NodeInfoAdapter extends RecyclerView.Adapter<NodeInfoAdapter.ViewHo
if (nodeInfo.isValid()) {
final double ping = nodeInfo.getResponseTime();
if (ping < NodeInfo.PING_GOOD) {
return R.drawable.ic_signal_wifi_4_bar_black_24dp;
return R.drawable.ic_signal_wifi_4_bar_24dp;
} else if (ping < NodeInfo.PING_MEDIUM) {
return R.drawable.ic_signal_wifi_3_bar_black_24dp;
return R.drawable.ic_signal_wifi_3_bar_24dp;
} else if (ping < NodeInfo.PING_BAD) {
return R.drawable.ic_signal_wifi_2_bar_black_24dp;
return R.drawable.ic_signal_wifi_2_bar_24dp;
} else {
return R.drawable.ic_signal_wifi_1_bar_black_24dp;
return R.drawable.ic_signal_wifi_1_bar_24dp;
}
} else {
return R.drawable.ic_signal_wifi_off_black_24dp;
return R.drawable.ic_signal_wifi_off_24dp;
}
}

Some files were not shown because too many files have changed in this diff Show More