1
mirror of https://github.com/m2049r/xmrwallet synced 2025-09-06 02:27:11 +02:00

Compare commits

...

60 Commits

Author SHA1 Message Date
m2049r
a6e9d0e77c use yadio for pricing "exotic" fiat (#921)
* yadio api

* add more currencies

* fix es typo

* bump version & fix cicleci build
2023-12-10 14:24:35 +01:00
m2049r
17df7c3faf Pocket Change V2 (#914)
* show PC on btc confirm
* random slots to refill
2023-08-28 19:24:45 +02:00
m2049r
bf1829f775 PocketChange (#901) 2023-06-05 05:03:51 +02:00
m2049r
bc4aa0f772 Feature v0.18.2.2 (#900)
* add Ledger Stax

* update block heights

* reestimate restore height only for mainnet

* upgrade to gradle 8.0.1

* upgrade dependencies
2023-05-29 17:01:07 +02:00
m2049r
3f09e73df7 Merge pull request #898 from m2049r/feature_tweaks
UI tweaks
2023-05-03 23:13:21 +02:00
m2049r
11b7e23ad2 remove RUB as currency as we don't get an exchange rate for it 2023-05-03 22:49:18 +02:00
m2049r
ae48027689 new qr code logo 2023-05-03 22:43:42 +02:00
m2049r
a42f750fc4 center sync status 2023-05-03 08:22:23 +02:00
m2049r
3406f585f2 organize all imports 2023-04-30 17:46:58 +02:00
m2049r
7546637c89 remove NFC support 2023-04-30 17:43:51 +02:00
m2049r
4da2106f04 show active account in drawer 2023-04-30 17:16:20 +02:00
m2049r
93c11fb90e update build tools version 2023-04-30 17:04:05 +02:00
m2049r
9fa710f75b fix build warnings 2023-04-27 23:58:08 +02:00
m2049r
c53dd300bc update dependencies 2023-04-26 08:39:30 +02:00
m2049r
97f40648be make streetmode label better 2023-04-26 08:25:33 +02:00
m2049r
1ece6bfbeb move status above sum 2023-04-26 08:15:02 +02:00
m2049r
4b3b99ff2a fix colour of service logo & use it for receive qr code 2023-04-26 07:55:26 +02:00
m2049r
ca833d7017 show full subaddress in details 2023-04-26 07:38:14 +02:00
m2049r
f1b6f859de show subaddress info above label 2023-04-26 07:34:18 +02:00
m2049r
61d19c7066 remove next arrow 2023-04-26 07:25:04 +02:00
m2049r
ffda0e965b bump version 2023-01-07 11:07:19 +01:00
m2049r
cc7cdb383c tweak http timeouts so sideshift does not timeout (#881) 2023-01-07 10:22:21 +01:00
m2049r
ac1ea05ef6 add unlockTime (#880)
show lock icon for currently locked txs
2023-01-07 10:19:22 +01:00
m2049r
1ddd4f30b9 use monero v0.18.1.2 (#878) 2022-12-04 21:04:15 +01:00
m2049r
1dc081834f bump version 2022-10-22 11:33:11 +02:00
m2049r
ce084927e1 fix langauge list 2022-10-22 11:32:44 +02:00
Kartal Kaan Bozdoğan
3610781f43 Display the unconfirmed amount in the chosen currency (#844)
Changed the translations accordingly
2022-10-22 10:59:25 +02:00
m2049r
ef3ddbac71 fix versions 2022-08-13 23:24:57 +02:00
m2049r
0512af1496 Monero v0.18.1.0 2022-08-13 10:20:21 +02:00
m2049r
bd2c49669a Feature v18 (#860)
* versions

* remove x86 builds
2022-08-10 16:50:18 +02:00
Kartal Kaan Bozdoğan
ac7831d0f9 Upgrade to 0.18.0.0 Fluorine Fermi (#856)
* Upgrade to Monero wallet 0.18.0.0 Fluorine Fermi
2022-08-05 01:09:56 +02:00
Kartal Kaan Bozdoğan
0f0b9a38c7 Fix new wallet restore height (#858)
* New wallets: set current block height as the restore height.
  Go back 4 days for estimated heights
2022-08-05 01:09:10 +02:00
Kartal Kaan Bozdoğan
807db19603 Fixed zlib hashes (#845) 2022-08-05 01:02:34 +02:00
m2049r
c956f38899 remove S for Nano 2022-05-23 19:47:53 +02:00
m2049r
db68f517d3 bump version 2022-05-23 19:31:22 +02:00
m2049r
d4b293af80 new strings (#839) 2022-05-23 19:20:28 +02:00
m2049r
f7bbfc2fac remove untranslatables (#838) 2022-05-23 19:16:49 +02:00
m2049r
e08964749e Fix entities (#837)
* remove ✓

* resolve nbsp
2022-05-23 19:03:45 +02:00
Dave Scotese
a05fa9d177 Exchange rate was hard to find. (#763)
The FAQ I added uses both "exchange" and "rate," neither of which appeared in the FAQ otherwise.
2022-05-23 18:42:30 +02:00
kivojo
7fe2fbe37d Translation to Farsi/Persian (#815)
* about.xml translated to Farsi

* minor improvements in translation

* one small typo

* help.xml translated to Farsi

* <br/> tags fixed

* better translation of word Mnemonic to Farsi

* strings.xml translated to Farsi
READY for PR!

* oops, my bad! deleted the untranslatable strings.

Co-authored-by: kivojo <user@example.com>
2022-05-23 18:41:06 +02:00
kingoflove819
40e30fed08 Create about.xml (#809)
* Create about.xml

* Update about.xml

* Completed translating about.xml for tamil
2022-05-23 18:39:38 +02:00
kingoflove819
320c7865ff Create help.xml (#810)
* Create help.xml

* Update help.xml

* Update help.xml

* Update help.xml

* Update help.xml
2022-05-23 18:39:23 +02:00
kingoflove819
5e8cf8010e Create strings.xml (#811)
* Create strings.xml

* Update strings.xml

* Update strings.xml

* Update strings.xml

* Update strings.xml

* Completed strings.xml
2022-05-23 18:39:07 +02:00
Age Bosma
e671fa19e0 Specify wallet folder (#835)
* Specify wallet folder

* Update FAQ.md
2022-05-23 18:36:22 +02:00
m2049r
20d5b9a100 fix sweep to be invisible by default 2022-05-15 21:56:38 +02:00
m2049r
5d489a634b bump version 2022-05-15 17:25:28 +02:00
m2049r
59b6f484fd update to monero v0.17.3.2 2022-05-15 17:24:54 +02:00
m2049r
ecaa49d67d upgrade build files 2022-05-15 15:57:11 +02:00
jont4
d2dc53599e Update PT-rBR strings (#813)
* Update pt-rBR

* Update app/src/main/res/values-pt-rBR/strings.xml

Co-authored-by: netrik182 <30935310+netrik182@users.noreply.github.com>

* Update app/src/main/res/values-pt-rBR/strings.xml

Co-authored-by: netrik182 <30935310+netrik182@users.noreply.github.com>

* Update strings.xml

fix as suggested

Co-authored-by: jontaix <31804298+jontaix@users.noreply.github.com>
Co-authored-by: netrik182 <30935310+netrik182@users.noreply.github.com>
Co-authored-by: m2049r <m2049r@monerujo.io>
2022-05-01 11:51:49 +02:00
Лапки
4d8b26f97f Update strings.xml (#826) 2022-05-01 11:44:52 +02:00
Justin Berman
581c76e7be setName uses async network helper in case of reverse DNS lookup (#818, #827) (#828) 2022-05-01 11:44:27 +02:00
AnonimaUzanto
6f66862870 Adding support for Ledger Nano S Plus (#832) 2022-05-01 11:35:01 +02:00
m2049r
dd92f7bb36 bump version 2022-03-13 15:37:28 +01:00
m2049r
46808d306b clean transitions 2022-03-12 23:10:34 +01:00
m2049r
20503d2cbd remove send/receive transitions 2022-03-11 00:25:50 +01:00
m2049r
604691ca7e fix FABs 2022-03-10 21:06:19 +01:00
m2049r
1b626ba2b0 improve transitions 2022-03-10 20:57:57 +01:00
m2049r
0ed7bdfcee remove test Dockerfile 2022-03-10 09:07:14 +01:00
m2049r
524c3dd79f upgrade ci image to 2022.03-ndk (#822) 2022-03-10 09:04:43 +01:00
m2049r
197dffeae1 fix tests 2022-03-10 07:53:52 +01:00
148 changed files with 4664 additions and 1429 deletions

View File

@@ -3,13 +3,11 @@ jobs:
build: build:
working_directory: ~/code working_directory: ~/code
docker: docker:
- image: circleci/android:api-28-ndk - image: cimg/android:2023.12-ndk
environment: environment:
JVM_OPTS: -Xmx3200m JVM_OPTS: -Xmx3200m
steps: steps:
- checkout - checkout
- run: yes | sdkmanager --licenses || exit 0
- run: yes | sdkmanager --update || exit 0
- restore_cache: - restore_cache:
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }} key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}
- run: - run:

View File

@@ -1,4 +1,5 @@
cmake_minimum_required(VERSION 3.4.1) cmake_minimum_required(VERSION 3.4.1)
project(monerujo)
message(STATUS ABI_INFO = ${ANDROID_ABI}) message(STATUS ABI_INFO = ${ANDROID_ABI})
add_library( monerujo add_library( monerujo
@@ -121,7 +122,7 @@ set_target_properties(easylogging PROPERTIES IMPORTED_LOCATION
add_library(unbound STATIC IMPORTED) add_library(unbound STATIC IMPORTED)
set_target_properties(unbound PROPERTIES IMPORTED_LOCATION set_target_properties(unbound PROPERTIES IMPORTED_LOCATION
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libunbound.a) ${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libunbound.a)
add_library(epee STATIC IMPORTED) add_library(epee STATIC IMPORTED)
set_target_properties(epee PROPERTIES IMPORTED_LOCATION set_target_properties(epee PROPERTIES IMPORTED_LOCATION

View File

@@ -1,15 +1,15 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
android { android {
compileSdkVersion 31
buildToolsVersion '30.0.3'
ndkVersion '17.2.4988734' ndkVersion '17.2.4988734'
defaultConfig { defaultConfig {
applicationId "com.m2049r.xmrwallet" applicationId "com.m2049r.xmrwallet"
buildToolsVersion = '34.0.0'
compileSdk 33
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 31 targetSdkVersion 33
versionCode 1303 versionCode 3310
versionName "2.3.3 'Baldaŭ'" versionName "3.3.10 'Argentina'"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild { externalNativeBuild {
cmake { cmake {
@@ -72,7 +72,7 @@ android {
abi { abi {
enable true enable true
reset() reset()
include 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64' include 'armeabi-v7a', 'arm64-v8a', 'x86_64'
universalApk true universalApk true
} }
} }
@@ -111,6 +111,7 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8
} }
namespace 'com.m2049r.xmrwallet'
} }
static def getId(name) { static def getId(name) {
@@ -120,16 +121,18 @@ static def getId(name) {
} }
dependencies { dependencies {
implementation 'androidx.core:core:1.7.0' implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.0"))
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'androidx.core:core:1.10.1'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.2.1' implementation 'androidx.recyclerview:recyclerview:1.3.1'
implementation 'androidx.cardview:cardview:1.0.0' implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3' implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.preference:preference:1.2.0' implementation 'androidx.preference:preference:1.2.1'
implementation 'com.google.android.material:material:1.5.0' implementation 'com.google.android.material:material:1.9.0'
implementation 'me.dm7.barcodescanner:zxing:1.9.8' implementation 'me.dm7.barcodescanner:zxing:1.9.8'
implementation "com.squareup.okhttp3:okhttp:4.9.3" implementation "com.squareup.okhttp3:okhttp:4.9.3"

View File

@@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android">
package="com.m2049r.xmrwallet">
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
@@ -8,7 +11,6 @@
<uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.USE_BIOMETRIC" /> <uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<queries> <queries>

File diff suppressed because it is too large Load Diff

View File

@@ -20,8 +20,6 @@
package com.btchip.comm; package com.btchip.comm;
import com.btchip.BTChipException;
public interface BTChipTransport { public interface BTChipTransport {
byte[] exchange(byte[] command); byte[] exchange(byte[] command);

View File

@@ -28,7 +28,6 @@ import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager; import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbRequest; import android.hardware.usb.UsbRequest;
import com.btchip.BTChipException;
import com.btchip.comm.BTChipTransport; import com.btchip.comm.BTChipTransport;
import com.btchip.comm.LedgerHelper; import com.btchip.comm.LedgerHelper;
import com.btchip.utils.Dump; import com.btchip.utils.Dump;
@@ -78,7 +77,7 @@ public class BTChipTransportAndroidHID implements BTChipTransport {
} }
private static final int VID = 0x2C97; private static final int VID = 0x2C97;
private static final int[] PID_HIDS = {0x0001, 0x0004}; private static final int[] PID_HIDS = {0x0001, 0x0004, 0x0005};
private UsbDeviceConnection connection; private UsbDeviceConnection connection;
private UsbInterface dongleInterface; private UsbInterface dongleInterface;

View File

@@ -16,36 +16,18 @@
package com.m2049r.xmrwallet; package com.m2049r.xmrwallet;
import android.app.PendingIntent;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.nfc.FormatException;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.Ndef;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.os.PowerManager; import android.os.PowerManager;
import android.widget.Toast;
import androidx.annotation.CallSuper; import androidx.annotation.CallSuper;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.m2049r.xmrwallet.data.BarcodeData; import com.m2049r.xmrwallet.data.BarcodeData;
import com.m2049r.xmrwallet.dialog.ProgressDialog; import com.m2049r.xmrwallet.dialog.ProgressDialog;
import com.m2049r.xmrwallet.fragment.send.SendFragment;
import com.m2049r.xmrwallet.ledger.Ledger; import com.m2049r.xmrwallet.ledger.Ledger;
import com.m2049r.xmrwallet.ledger.LedgerProgressDialog; import com.m2049r.xmrwallet.ledger.LedgerProgressDialog;
import java.io.IOException;
import timber.log.Timber; import timber.log.Timber;
public class BaseActivity extends SecureActivity public class BaseActivity extends SecureActivity
@@ -141,91 +123,6 @@ public class BaseActivity extends SecureActivity
Timber.d("WakeLock released"); Timber.d("WakeLock released");
} }
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initNfc();
}
@Override
protected void onPostResume() {
super.onPostResume();
if (nfcAdapter != null) {
nfcAdapter.enableForegroundDispatch(this, nfcPendingIntent, null, null);
// intercept all techs so we can tell the user their tag is no good
}
}
@Override
protected void onPause() {
Timber.d("onPause()");
if (nfcAdapter != null)
nfcAdapter.disableForegroundDispatch(this);
super.onPause();
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
processNfcIntent(intent);
}
// NFC stuff
private NfcAdapter nfcAdapter;
private PendingIntent nfcPendingIntent;
public void initNfc() {
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null) // no NFC support
return;
nfcPendingIntent = PendingIntent.getActivity(this, 0,
new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_IMMUTABLE : 0);
}
private void processNfcIntent(Intent intent) {
String action = intent.getAction();
Timber.d("ACTION=%s", action);
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
Ndef ndef = Ndef.get(tag);
if (ndef == null) {
Toast.makeText(this, getString(R.string.nfc_tag_unsupported), Toast.LENGTH_LONG).show();
return;
}
Fragment f = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
if (f instanceof ReceiveFragment) {
// We want to write a Tag from the ReceiveFragment
BarcodeData bc = ((ReceiveFragment) f).getBarcodeData();
if (bc != null) {
new AsyncWriteTag(ndef, bc.getUri()).execute();
} // else wallet is not loaded yet or receive is otherwise not ready - ignore
} else if (f instanceof SendFragment) {
// We want to read a Tag for the SendFragment
NdefMessage ndefMessage = ndef.getCachedNdefMessage();
if (ndefMessage == null) {
Toast.makeText(this, getString(R.string.nfc_tag_read_undef), Toast.LENGTH_LONG).show();
return;
}
NdefRecord firstRecord = ndefMessage.getRecords()[0];
Uri uri = firstRecord.toUri(); // we insist on the first record
if (uri == null) {
Toast.makeText(this, getString(R.string.nfc_tag_read_undef), Toast.LENGTH_LONG).show();
} else {
BarcodeData bc = BarcodeData.fromString(uri.toString());
if (bc == null)
Toast.makeText(this, getString(R.string.nfc_tag_read_undef), Toast.LENGTH_LONG).show();
else
onUriScanned(bc);
}
}
}
}
// this gets called only if we get data // this gets called only if we get data
@CallSuper @CallSuper
void onUriScanned(BarcodeData barcodeData) { void onUriScanned(BarcodeData barcodeData) {
@@ -239,75 +136,4 @@ public class BaseActivity extends SecureActivity
barcodeData = null; barcodeData = null;
return popped; return popped;
} }
private class AsyncWriteTag extends AsyncTask<Void, Void, Boolean> {
Ndef ndef;
Uri uri;
String errorMessage = null;
AsyncWriteTag(Ndef ndef, Uri uri) {
this.ndef = ndef;
this.uri = uri;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
showProgressDialog(R.string.progress_nfc_write);
}
@Override
protected Boolean doInBackground(Void... params) {
if (params.length != 0) return false;
try {
writeNdef(ndef, uri);
return true;
} catch (IOException | FormatException ex) {
Timber.e(ex);
} catch (IllegalArgumentException ex) {
errorMessage = ex.getMessage();
Timber.d(errorMessage);
} finally {
try {
ndef.close();
} catch (IOException ex) {
Timber.e(ex);
}
}
return false;
}
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
if (isDestroyed()) {
return;
}
dismissProgressDialog();
if (!result) {
if (errorMessage != null)
Toast.makeText(getApplicationContext(), errorMessage, Toast.LENGTH_LONG).show();
else
Toast.makeText(getApplicationContext(), getString(R.string.nfc_write_failed), Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), getString(R.string.nfc_write_successful), Toast.LENGTH_SHORT).show();
}
}
}
void writeNdef(Ndef ndef, Uri uri) throws IOException, FormatException {
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null) return; // no NFC support here
NdefRecord recordNFC = NdefRecord.createUri(uri);
NdefMessage message = new NdefMessage(recordNFC);
ndef.connect();
int tagSize = ndef.getMaxSize();
int msgSize = message.getByteArrayLength();
Timber.d("tagSize=%d, msgSIze=%d, uriSize=%d", tagSize, msgSize, uri.toString().length());
if (tagSize < msgSize)
throw new IllegalArgumentException(getString(R.string.nfc_tag_size, tagSize, msgSize));
ndef.writeNdefMessage(message);
}
} }

View File

@@ -16,8 +16,6 @@
package com.m2049r.xmrwallet; package com.m2049r.xmrwallet;
import androidx.annotation.NonNull;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
@@ -37,6 +35,7 @@ import android.view.inputmethod.EditorInfo;
import android.widget.Button; import android.widget.Button;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
@@ -44,6 +43,7 @@ import androidx.fragment.app.Fragment;
import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.switchmaterial.SwitchMaterial; import com.google.android.material.switchmaterial.SwitchMaterial;
import com.google.android.material.textfield.TextInputLayout; import com.google.android.material.textfield.TextInputLayout;
import com.m2049r.xmrwallet.model.NetworkType;
import com.m2049r.xmrwallet.model.Wallet; import com.m2049r.xmrwallet.model.Wallet;
import com.m2049r.xmrwallet.model.WalletManager; import com.m2049r.xmrwallet.model.WalletManager;
import com.m2049r.xmrwallet.util.FingerprintHelper; import com.m2049r.xmrwallet.util.FingerprintHelper;
@@ -345,21 +345,23 @@ public class GenerateFragment extends Fragment {
String restoreHeight = etWalletRestoreHeight.getEditText().getText().toString().trim(); String restoreHeight = etWalletRestoreHeight.getEditText().getText().toString().trim();
if (restoreHeight.isEmpty()) return -1; if (restoreHeight.isEmpty()) return -1;
try { if (WalletManager.getInstance().getNetworkType() == NetworkType.NetworkType_Mainnet) {
// is it a date?
SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd");
parser.setLenient(false);
height = RestoreHeight.getInstance().getHeight(parser.parse(restoreHeight));
} catch (ParseException ignored) {
}
if ((height < 0) && (restoreHeight.length() == 8))
try { try {
// is it a date without dashes? // is it a date?
SimpleDateFormat parser = new SimpleDateFormat("yyyyMMdd"); SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd");
parser.setLenient(false); parser.setLenient(false);
height = RestoreHeight.getInstance().getHeight(parser.parse(restoreHeight)); height = RestoreHeight.getInstance().getHeight(parser.parse(restoreHeight));
} catch (ParseException ignored) { } catch (ParseException ignored) {
} }
if ((height < 0) && (restoreHeight.length() == 8))
try {
// is it a date without dashes?
SimpleDateFormat parser = new SimpleDateFormat("yyyyMMdd");
parser.setLenient(false);
height = RestoreHeight.getInstance().getHeight(parser.parse(restoreHeight));
} catch (ParseException ignored) {
}
}
if (height < 0) if (height < 0)
try { try {
// or is it a height? // or is it a height?

View File

@@ -49,7 +49,6 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.m2049r.xmrwallet.data.DefaultNodes; import com.m2049r.xmrwallet.data.DefaultNodes;
import com.m2049r.xmrwallet.data.Node; import com.m2049r.xmrwallet.data.Node;
import com.m2049r.xmrwallet.data.NodeInfo; import com.m2049r.xmrwallet.data.NodeInfo;
import com.m2049r.xmrwallet.dialog.CreditsFragment;
import com.m2049r.xmrwallet.dialog.HelpFragment; import com.m2049r.xmrwallet.dialog.HelpFragment;
import com.m2049r.xmrwallet.ledger.Ledger; import com.m2049r.xmrwallet.ledger.Ledger;
import com.m2049r.xmrwallet.ledger.LedgerProgressDialog; import com.m2049r.xmrwallet.ledger.LedgerProgressDialog;
@@ -659,11 +658,11 @@ public class LoginActivity extends BaseActivity
break; break;
case NetworkType_Testnet: case NetworkType_Testnet:
toolbar.setSubtitle(getString(R.string.connect_testnet)); toolbar.setSubtitle(getString(R.string.connect_testnet));
toolbar.setBackgroundResource(ThemeHelper.getThemedResourceId(this, R.attr.colorPrimaryDark)); toolbar.setBackgroundResource(ThemeHelper.getThemedResourceId(this, androidx.appcompat.R.attr.colorPrimaryDark));
break; break;
case NetworkType_Stagenet: case NetworkType_Stagenet:
toolbar.setSubtitle(getString(R.string.connect_stagenet)); toolbar.setSubtitle(getString(R.string.connect_stagenet));
toolbar.setBackgroundResource(ThemeHelper.getThemedResourceId(this, R.attr.colorPrimaryDark)); toolbar.setBackgroundResource(ThemeHelper.getThemedResourceId(this, androidx.appcompat.R.attr.colorPrimaryDark));
break; break;
default: default:
throw new IllegalStateException("NetworkType unknown: " + net); throw new IllegalStateException("NetworkType unknown: " + net);
@@ -916,9 +915,9 @@ public class LoginActivity extends BaseActivity
@Override @Override
public boolean createWallet(File aFile, String password) { public boolean createWallet(File aFile, String password) {
NodeInfo currentNode = getNode(); NodeInfo currentNode = getNode();
// get it from the connected node if we have one, and go back ca. 4 days // get it from the connected node if we have one
final long restoreHeight = final long restoreHeight =
(currentNode != null) ? currentNode.getHeight() - 2000 : -1; (currentNode != null) ? currentNode.getHeight() : -1;
Wallet newWallet = WalletManager.getInstance() Wallet newWallet = WalletManager.getInstance()
.createWallet(aFile, password, MNEMONIC_LANGUAGE, restoreHeight); .createWallet(aFile, password, MNEMONIC_LANGUAGE, restoreHeight);
return checkAndCloseWallet(newWallet); return checkAndCloseWallet(newWallet);

View File

@@ -29,7 +29,6 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.animation.Animation; import android.view.animation.Animation;
import android.view.animation.AnimationUtils; import android.view.animation.AnimationUtils;
import android.widget.FrameLayout;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.RelativeLayout; import android.widget.RelativeLayout;

View File

@@ -20,7 +20,6 @@ import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.m2049r.xmrwallet.onboarding.OnBoardingActivity; import com.m2049r.xmrwallet.onboarding.OnBoardingActivity;
import com.m2049r.xmrwallet.onboarding.OnBoardingManager; import com.m2049r.xmrwallet.onboarding.OnBoardingManager;

View File

@@ -415,7 +415,14 @@ public class NodeFragment extends Fragment
} }
etNodeHost.setError(null); etNodeHost.setError(null);
nodeInfo.setRpcPort(port); nodeInfo.setRpcPort(port);
nodeInfo.setName(etNodeName.getEditText().getText().toString().trim()); // setName() may trigger reverse DNS
Helper.runWithNetwork(new Helper.Action() {
@Override
public boolean run() {
nodeInfo.setName(etNodeName.getEditText().getText().toString().trim());
return true;
}
});
nodeInfo.setUsername(etNodeUser.getEditText().getText().toString().trim()); nodeInfo.setUsername(etNodeUser.getEditText().getText().toString().trim());
nodeInfo.setPassword(etNodePass.getEditText().getText().toString()); // no trim for pw nodeInfo.setPassword(etNodePass.getEditText().getText().toString()); // no trim for pw
return true; return true;

View File

@@ -22,7 +22,6 @@ import android.graphics.Bitmap;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable;
import android.net.Uri; import android.net.Uri;
import android.nfc.NfcManager;
import android.os.Bundle; import android.os.Bundle;
import android.text.Editable; import android.text.Editable;
import android.text.Html; import android.text.Html;
@@ -191,11 +190,6 @@ public class ReceiveFragment extends Fragment {
throw new IllegalStateException("no wallet info"); throw new IllegalStateException("no wallet info");
} }
View tvNfc = view.findViewById(R.id.tvNfc);
NfcManager manager = (NfcManager) getContext().getSystemService(Context.NFC_SERVICE);
if ((manager != null) && (manager.getDefaultAdapter() != null))
tvNfc.setVisibility(View.VISIBLE);
return view; return view;
} }
@@ -403,7 +397,7 @@ public class ReceiveFragment extends Fragment {
private Bitmap getMoneroLogo() { private Bitmap getMoneroLogo() {
if (logo == null) { if (logo == null) {
logo = Helper.getBitmap(getContext(), R.drawable.ic_monero_logo_b); logo = Helper.getBitmap(getContext(), R.drawable.ic_monerujo_qr);
} }
return logo; return logo;
} }

View File

@@ -19,12 +19,13 @@ package com.m2049r.xmrwallet;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Toast; import android.widget.Toast;
import androidx.fragment.app.Fragment;
import com.google.zxing.BarcodeFormat; import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result; import com.google.zxing.Result;

View File

@@ -16,6 +16,8 @@
package com.m2049r.xmrwallet; package com.m2049r.xmrwallet;
import static android.view.WindowManager.LayoutParams;
import android.content.Context; import android.content.Context;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.os.Build; import android.os.Build;
@@ -29,8 +31,6 @@ import com.m2049r.xmrwallet.util.LocaleHelper;
import java.util.Locale; import java.util.Locale;
import static android.view.WindowManager.LayoutParams;
public abstract class SecureActivity extends AppCompatActivity { public abstract class SecureActivity extends AppCompatActivity {
@Override @Override
protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) {

View File

@@ -30,7 +30,6 @@ import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.transition.MaterialElevationScale;
import com.m2049r.xmrwallet.data.Subaddress; import com.m2049r.xmrwallet.data.Subaddress;
import com.m2049r.xmrwallet.layout.SubaddressInfoAdapter; import com.m2049r.xmrwallet.layout.SubaddressInfoAdapter;
import com.m2049r.xmrwallet.ledger.LedgerProgressDialog; import com.m2049r.xmrwallet.ledger.LedgerProgressDialog;
@@ -117,14 +116,6 @@ public class SubaddressFragment extends Fragment implements SubaddressInfoAdapte
managerMode = ((b != null) && (MODE_MANAGER.equals(b.getString(KEY_MODE)))); managerMode = ((b != null) && (MODE_MANAGER.equals(b.getString(KEY_MODE))));
View view = inflater.inflate(R.layout.fragment_subaddress, container, false); View view = inflater.inflate(R.layout.fragment_subaddress, container, false);
final MaterialElevationScale exitTransition = new MaterialElevationScale(false);
exitTransition.setDuration(getResources().getInteger(R.integer.tx_item_transition_duration));
setExitTransition(exitTransition);
final MaterialElevationScale reenterTransition = new MaterialElevationScale(true);
reenterTransition.setDuration(getResources().getInteger(R.integer.tx_item_transition_duration));
setReenterTransition(reenterTransition);
view.findViewById(R.id.fab).setOnClickListener(this); view.findViewById(R.id.fab).setOnClickListener(this);
if (managerMode) { if (managerMode) {
@@ -154,11 +145,6 @@ public class SubaddressFragment extends Fragment implements SubaddressInfoAdapte
@Override @Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
postponeEnterTransition();
view.getViewTreeObserver().addOnPreDrawListener(() -> {
startPostponedEnterTransition();
return true;
});
} }
public void loadList() { public void loadList() {
@@ -252,4 +238,5 @@ public class SubaddressFragment extends Fragment implements SubaddressInfoAdapte
activityCallback.showSubaddress(view, subaddress.getAddressIndex()); activityCallback.showSubaddress(view, subaddress.getAddressIndex());
return false; return false;
} }
} }

View File

@@ -29,15 +29,15 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import androidx.transition.Transition;
import androidx.transition.TransitionInflater;
import com.google.android.material.textfield.TextInputLayout; import com.google.android.material.textfield.TextInputLayout;
import com.google.android.material.transition.MaterialContainerTransform;
import com.m2049r.xmrwallet.data.Subaddress; import com.m2049r.xmrwallet.data.Subaddress;
import com.m2049r.xmrwallet.layout.TransactionInfoAdapter; import com.m2049r.xmrwallet.layout.TransactionInfoAdapter;
import com.m2049r.xmrwallet.model.TransactionInfo; import com.m2049r.xmrwallet.model.TransactionInfo;
import com.m2049r.xmrwallet.model.Wallet; import com.m2049r.xmrwallet.model.Wallet;
import com.m2049r.xmrwallet.util.Helper; import com.m2049r.xmrwallet.util.Helper;
import com.m2049r.xmrwallet.util.ThemeHelper;
import com.m2049r.xmrwallet.widget.Toolbar; import com.m2049r.xmrwallet.widget.Toolbar;
import java.util.ArrayList; import java.util.ArrayList;
@@ -46,7 +46,7 @@ import java.util.List;
import timber.log.Timber; import timber.log.Timber;
public class SubaddressInfoFragment extends Fragment public class SubaddressInfoFragment extends Fragment
implements TransactionInfoAdapter.OnInteractionListener, OnBlockUpdateListener { implements TransactionInfoAdapter.Listener, OnBlockUpdateListener {
private TransactionInfoAdapter adapter; private TransactionInfoAdapter adapter;
private Subaddress subaddress; private Subaddress subaddress;
@@ -76,7 +76,7 @@ public class SubaddressInfoFragment extends Fragment
etName.getEditText().setText(subaddress.getDisplayLabel()); etName.getEditText().setText(subaddress.getDisplayLabel());
tvAddress.setText(getContext().getString(R.string.subbaddress_info_subtitle, tvAddress.setText(getContext().getString(R.string.subbaddress_info_subtitle,
subaddress.getAddressIndex(), subaddress.getSquashedAddress())); subaddress.getAddressIndex(), subaddress.getAddress()));
etName.getEditText().setOnFocusChangeListener((v, hasFocus) -> { etName.getEditText().setOnFocusChangeListener((v, hasFocus) -> {
if (!hasFocus) { if (!hasFocus) {
@@ -102,10 +102,8 @@ public class SubaddressInfoFragment extends Fragment
@Override @Override
public void onCreate(@Nullable Bundle savedInstanceState) { public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
final MaterialContainerTransform transform = new MaterialContainerTransform(); Transition transform = TransitionInflater.from(requireContext())
transform.setDrawingViewId(R.id.fragment_container); .inflateTransition(R.transition.details);
transform.setDuration(getResources().getInteger(R.integer.tx_item_transition_duration));
transform.setAllContainerColors(ThemeHelper.getThemedColor(getContext(), android.R.attr.colorBackground));
setSharedElementEnterTransition(transform); setSharedElementEnterTransition(transform);
} }
@@ -147,6 +145,8 @@ public class SubaddressInfoFragment extends Fragment
void setTitle(String title, String subtitle); void setTitle(String title, String subtitle);
void setSubtitle(String subtitle); void setSubtitle(String subtitle);
long getDaemonHeight();
} }
@Override @Override
@@ -172,4 +172,9 @@ public class SubaddressInfoFragment extends Fragment
public void onPause() { public void onPause() {
super.onPause(); super.onPause();
} }
@Override
public long getDaemonHeight() {
return activityCallback.getDaemonHeight();
}
} }

View File

@@ -36,9 +36,9 @@ import android.widget.Toast;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.transition.Transition;
import androidx.transition.TransitionInflater;
import com.google.android.material.transition.MaterialContainerTransform;
import com.google.android.material.transition.MaterialElevationScale;
import com.m2049r.xmrwallet.data.Subaddress; import com.m2049r.xmrwallet.data.Subaddress;
import com.m2049r.xmrwallet.data.UserNotes; import com.m2049r.xmrwallet.data.UserNotes;
import com.m2049r.xmrwallet.model.TransactionInfo; import com.m2049r.xmrwallet.model.TransactionInfo;
@@ -79,10 +79,14 @@ public class TxFragment extends Fragment {
private TextView tvTxPaymentId; private TextView tvTxPaymentId;
private TextView tvTxBlockheight; private TextView tvTxBlockheight;
private TextView tvTxAmount; private TextView tvTxAmount;
private TextView tvTxPocketChangeAmount;
private TextView tvTxFee; private TextView tvTxFee;
private TextView tvTxTransfers; private TextView tvTxTransfers;
private TextView etTxNotes; private TextView etTxNotes;
private View llWarning;
private TextView tvWarning;
// XMRTO stuff // XMRTO stuff
private View cvXmrTo; private View cvXmrTo;
private TextView tvTxXmrToKey; private TextView tvTxXmrToKey;
@@ -96,13 +100,6 @@ public class TxFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_tx_info, container, false); View view = inflater.inflate(R.layout.fragment_tx_info, container, false);
final MaterialElevationScale exitTransition = new MaterialElevationScale(false);
exitTransition.setDuration(getResources().getInteger(R.integer.tx_item_transition_duration));
setExitTransition(exitTransition);
final MaterialElevationScale reenterTransition = new MaterialElevationScale(true);
reenterTransition.setDuration(getResources().getInteger(R.integer.tx_item_transition_duration));
setReenterTransition(reenterTransition);
cvXmrTo = view.findViewById(R.id.cvXmrTo); cvXmrTo = view.findViewById(R.id.cvXmrTo);
tvTxXmrToKey = view.findViewById(R.id.tvTxXmrToKey); tvTxXmrToKey = view.findViewById(R.id.tvTxXmrToKey);
tvDestinationBtc = view.findViewById(R.id.tvDestinationBtc); tvDestinationBtc = view.findViewById(R.id.tvDestinationBtc);
@@ -120,12 +117,15 @@ public class TxFragment extends Fragment {
tvTxPaymentId = view.findViewById(R.id.tvTxPaymentId); tvTxPaymentId = view.findViewById(R.id.tvTxPaymentId);
tvTxBlockheight = view.findViewById(R.id.tvTxBlockheight); tvTxBlockheight = view.findViewById(R.id.tvTxBlockheight);
tvTxAmount = view.findViewById(R.id.tvTxAmount); tvTxAmount = view.findViewById(R.id.tvTxAmount);
tvTxPocketChangeAmount = view.findViewById(R.id.tvTxPocketChangeAmount);
tvTxFee = view.findViewById(R.id.tvTxFee); tvTxFee = view.findViewById(R.id.tvTxFee);
tvTxTransfers = view.findViewById(R.id.tvTxTransfers); tvTxTransfers = view.findViewById(R.id.tvTxTransfers);
etTxNotes = view.findViewById(R.id.etTxNotes); etTxNotes = view.findViewById(R.id.etTxNotes);
etTxNotes.setRawInputType(InputType.TYPE_CLASS_TEXT); etTxNotes.setRawInputType(InputType.TYPE_CLASS_TEXT);
llWarning = view.findViewById(R.id.llWarning);
tvWarning = view.findViewById(R.id.tvWarning);
tvTxXmrToKey.setOnClickListener(v -> { tvTxXmrToKey.setOnClickListener(v -> {
Helper.clipBoardCopy(getActivity(), getString(R.string.label_copy_xmrtokey), tvTxXmrToKey.getText().toString()); Helper.clipBoardCopy(getActivity(), getString(R.string.label_copy_xmrtokey), tvTxXmrToKey.getText().toString());
Toast.makeText(getActivity(), getString(R.string.message_copy_xmrtokey), Toast.LENGTH_SHORT).show(); Toast.makeText(getActivity(), getString(R.string.message_copy_xmrtokey), Toast.LENGTH_SHORT).show();
@@ -251,8 +251,10 @@ public class TxFragment extends Fragment {
} }
String sign = (info.direction == TransactionInfo.Direction.Direction_In ? "+" : "-"); String sign = (info.direction == TransactionInfo.Direction.Direction_In ? "+" : "-");
long realAmount = info.amount; tvTxAmount.setText(sign + Wallet.getDisplayAmount(info.amount));
tvTxAmount.setText(sign + Wallet.getDisplayAmount(realAmount)); final long pcAmount = info.getPocketChangeAmount();
tvTxPocketChangeAmount.setVisibility(pcAmount > 0 ? View.VISIBLE : View.GONE);
tvTxPocketChangeAmount.setText(getString(R.string.pocketchange_tx_detail, Wallet.getDisplayAmount(pcAmount)));
if ((info.fee > 0)) { if ((info.fee > 0)) {
String fee = Wallet.getDisplayAmount(info.fee); String fee = Wallet.getDisplayAmount(info.fee);
@@ -306,6 +308,20 @@ public class TxFragment extends Fragment {
tvTxTransfers.setText(sb.toString()); tvTxTransfers.setText(sb.toString());
tvDestination.setText(dstSb.toString()); tvDestination.setText(dstSb.toString());
showBtcInfo(); showBtcInfo();
showLock();
}
private void showLock() {
llWarning.setVisibility(View.GONE);
if (info.unlockTime == 0) return;
final long blockheight = activityCallback.getDaemonHeight();
final long blocks = info.unlockTime - blockheight;
final double unlockDays = blocks / (30. * 24);
if (unlockDays > 0) {
llWarning.setVisibility(View.VISIBLE);
tvWarning.setText(getString(R.string.tx_locked, info.unlockTime, blocks, unlockDays));
}
} }
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
@@ -347,10 +363,8 @@ public class TxFragment extends Fragment {
public void onCreate(@Nullable Bundle savedInstanceState) { public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setHasOptionsMenu(true); setHasOptionsMenu(true);
final MaterialContainerTransform transform = new MaterialContainerTransform(); Transition transform = TransitionInflater.from(requireContext())
transform.setDrawingViewId(R.id.fragment_container); .inflateTransition(R.transition.details);
transform.setDuration(getResources().getInteger(R.integer.tx_item_transition_duration));
transform.setAllContainerColors(ThemeHelper.getThemedColor(getContext(), android.R.attr.colorBackground));
setSharedElementEnterTransition(transform); setSharedElementEnterTransition(transform);
} }
@@ -379,6 +393,7 @@ public class TxFragment extends Fragment {
void showSubaddress(View view, final int subaddressIndex); void showSubaddress(View view, final int subaddressIndex);
long getDaemonHeight();
} }
@Override @Override

View File

@@ -52,8 +52,8 @@ import com.m2049r.xmrwallet.data.BarcodeData;
import com.m2049r.xmrwallet.data.Subaddress; import com.m2049r.xmrwallet.data.Subaddress;
import com.m2049r.xmrwallet.data.TxData; import com.m2049r.xmrwallet.data.TxData;
import com.m2049r.xmrwallet.data.UserNotes; import com.m2049r.xmrwallet.data.UserNotes;
import com.m2049r.xmrwallet.dialog.CreditsFragment;
import com.m2049r.xmrwallet.dialog.HelpFragment; import com.m2049r.xmrwallet.dialog.HelpFragment;
import com.m2049r.xmrwallet.dialog.PocketChangeFragment;
import com.m2049r.xmrwallet.fragment.send.SendAddressWizardFragment; import com.m2049r.xmrwallet.fragment.send.SendAddressWizardFragment;
import com.m2049r.xmrwallet.fragment.send.SendFragment; import com.m2049r.xmrwallet.fragment.send.SendFragment;
import com.m2049r.xmrwallet.ledger.LedgerProgressDialog; import com.m2049r.xmrwallet.ledger.LedgerProgressDialog;
@@ -82,7 +82,8 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
WalletFragment.DrawerLocker, WalletFragment.DrawerLocker,
NavigationView.OnNavigationItemSelectedListener, NavigationView.OnNavigationItemSelectedListener,
SubaddressFragment.Listener, SubaddressFragment.Listener,
SubaddressInfoFragment.Listener { SubaddressInfoFragment.Listener,
PocketChangeFragment.Listener {
public static final String REQUEST_ID = "id"; public static final String REQUEST_ID = "id";
public static final String REQUEST_PW = "pw"; public static final String REQUEST_PW = "pw";
@@ -285,8 +286,6 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
onWalletRescan(); onWalletRescan();
} else if (itemId == R.id.action_info) { } else if (itemId == R.id.action_info) {
onWalletDetails(); onWalletDetails();
} else if (itemId == R.id.action_credits) {
CreditsFragment.display(getSupportFragmentManager());
} else if (itemId == R.id.action_share) { } else if (itemId == R.id.action_share) {
onShareTxInfo(); onShareTxInfo();
} else if (itemId == R.id.action_help_tx_info) { } else if (itemId == R.id.action_help_tx_info) {
@@ -301,6 +300,8 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
HelpFragment.display(getSupportFragmentManager(), R.string.help_send); HelpFragment.display(getSupportFragmentManager(), R.string.help_send);
} else if (itemId == R.id.action_rename) { } else if (itemId == R.id.action_rename) {
onAccountRename(); onAccountRename();
} else if (itemId == R.id.action_pocketchange) {
PocketChangeFragment.display(getSupportFragmentManager(), getWallet().getPocketChangeSetting());
} else if (itemId == R.id.action_subaddresses) { } else if (itemId == R.id.action_subaddresses) {
showSubaddresses(true); showSubaddresses(true);
} else if (itemId == R.id.action_streetmode) { } else if (itemId == R.id.action_streetmode) {
@@ -422,7 +423,7 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
break; break;
case NetworkType_Stagenet: case NetworkType_Stagenet:
case NetworkType_Testnet: case NetworkType_Testnet:
toolbar.setBackgroundResource(ThemeHelper.getThemedResourceId(this, R.attr.colorPrimaryDark)); toolbar.setBackgroundResource(ThemeHelper.getThemedResourceId(this, androidx.appcompat.R.attr.colorPrimaryDark));
break; break;
default: default:
throw new IllegalStateException("Unsupported Network: " + WalletManager.getInstance().getNetworkType()); throw new IllegalStateException("Unsupported Network: " + WalletManager.getInstance().getNetworkType());
@@ -451,7 +452,7 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
if (extras != null) { if (extras != null) {
String walletId = extras.getString(REQUEST_ID); String walletId = extras.getString(REQUEST_ID);
if (walletId != null) { if (walletId != null) {
setTitle(walletId, getString(R.string.status_wallet_connecting)); setTitle(walletId);
} }
} }
updateProgress(); updateProgress();
@@ -539,7 +540,7 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
@Override @Override
public void onSendRequest(View view) { public void onSendRequest(View view) {
replaceFragmentWithTransition(view, SendFragment.newInstance(uri), null, null); replaceFragment(SendFragment.newInstance(uri), null, null);
uri = null; // only use uri once uri = null; // only use uri once
} }
@@ -646,6 +647,8 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
haveWallet = true; haveWallet = true;
invalidateOptionsMenu(); invalidateOptionsMenu();
loadPocketChangeSettings();
if (requestStreetMode) onEnableStreetMode(); if (requestStreetMode) onEnableStreetMode();
final WalletFragment walletFragment = getWalletFragment(); final WalletFragment walletFragment = getWalletFragment();
@@ -800,10 +803,6 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
int transition; int transition;
if (newFragment instanceof TxFragment) if (newFragment instanceof TxFragment)
transition = R.string.tx_details_transition_name; transition = R.string.tx_details_transition_name;
else if (newFragment instanceof ReceiveFragment)
transition = R.string.receive_transition_name;
else if (newFragment instanceof SendFragment)
transition = R.string.send_transition_name;
else if (newFragment instanceof SubaddressInfoFragment) else if (newFragment instanceof SubaddressInfoFragment)
transition = R.string.subaddress_info_transition_name; transition = R.string.subaddress_info_transition_name;
else else
@@ -929,12 +928,8 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
@Override @Override
void onUriScanned(BarcodeData barcodeData) { void onUriScanned(BarcodeData barcodeData) {
super.onUriScanned(barcodeData); super.onUriScanned(barcodeData);
boolean processed = false;
if (onUriScannedListener != null) { if (onUriScannedListener != null) {
processed = onUriScannedListener.onUriScanned(barcodeData); onUriScannedListener.onUriScanned(barcodeData);
}
if (!processed || (onUriScannedListener == null)) {
Toast.makeText(this, getString(R.string.nfc_tag_read_what), Toast.LENGTH_LONG).show();
} }
} }
@@ -960,7 +955,7 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
Bundle b = new Bundle(); Bundle b = new Bundle();
b.putString("address", address); b.putString("address", address);
b.putString("name", getWalletName()); b.putString("name", getWalletName());
replaceFragmentWithTransition(view, new ReceiveFragment(), null, b); replaceFragment(new ReceiveFragment(), null, b);
Timber.d("ReceiveFragment placed"); Timber.d("ReceiveFragment placed");
} }
@@ -1032,13 +1027,14 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
final Wallet wallet = getWallet(); final Wallet wallet = getWallet();
if (wallet != null) { if (wallet != null) {
final int n = wallet.getNumAccounts(); final int n = wallet.getNumAccounts();
final int currentAccount = getWallet().getAccountIndex();
final boolean showBalances = (n > 1) && !isStreetMode(); final boolean showBalances = (n > 1) && !isStreetMode();
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
final String label = (showBalances ? final String label = (showBalances ?
getString(R.string.label_account, wallet.getAccountLabel(i), Helper.getDisplayAmount(wallet.getBalance(i), 2)) getString(R.string.label_account, wallet.getAccountLabel(i), Helper.getDisplayAmount(wallet.getBalance(i), 2))
: wallet.getAccountLabel(i)); : wallet.getAccountLabel(i));
final MenuItem item = menu.add(R.id.accounts_list, getAccountId(i), 2 * i, label); final MenuItem item = menu.add(R.id.accounts_list, getAccountId(i), 2 * i, label);
item.setIcon(R.drawable.ic_account_balance_wallet_black_24dp); item.setIcon(i == currentAccount ? R.drawable.ic_outline_folder_open_24 : R.drawable.ic_outline_folder_24);
if (i == wallet.getAccountIndex()) if (i == wallet.getAccountIndex())
item.setChecked(true); item.setChecked(true);
} }
@@ -1111,6 +1107,7 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
public void setAccountIndex(int accountIndex) { public void setAccountIndex(int accountIndex) {
getWallet().setAccountIndex(accountIndex); getWallet().setAccountIndex(accountIndex);
loadPocketChangeSettings();
selectedSubaddressIndex = 0; selectedSubaddressIndex = 0;
} }
@@ -1221,4 +1218,19 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
b.putInt("subaddressIndex", subaddressIndex); b.putInt("subaddressIndex", subaddressIndex);
replaceFragmentWithTransition(view, new SubaddressInfoFragment(), null, b); replaceFragmentWithTransition(view, new SubaddressInfoFragment(), null, b);
} }
@Override
public void setPocketChange(Wallet.PocketChangeSetting setting) {
SharedPreferences.Editor editor = getPrefs().edit();
editor.putString(getWallet().getAddress() + "_PC", setting.toPrefString());
editor.apply();
getWallet().setPocketChangeSetting(setting);
}
public void loadPocketChangeSettings() {
final String settings = getPrefs().getString(getWallet().getAddress() + "_PC", "0");
getWallet().setPocketChangeSetting(Wallet.PocketChangeSetting.from(settings));
}
} }

View File

@@ -43,7 +43,6 @@ import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.github.brnunes.swipeablerecyclerview.SwipeableRecyclerViewTouchListener; import com.github.brnunes.swipeablerecyclerview.SwipeableRecyclerViewTouchListener;
import com.google.android.material.transition.MaterialElevationScale;
import com.m2049r.xmrwallet.layout.TransactionInfoAdapter; import com.m2049r.xmrwallet.layout.TransactionInfoAdapter;
import com.m2049r.xmrwallet.model.TransactionInfo; import com.m2049r.xmrwallet.model.TransactionInfo;
import com.m2049r.xmrwallet.model.Wallet; import com.m2049r.xmrwallet.model.Wallet;
@@ -63,7 +62,7 @@ import java.util.List;
import timber.log.Timber; import timber.log.Timber;
public class WalletFragment extends Fragment public class WalletFragment extends Fragment
implements TransactionInfoAdapter.OnInteractionListener { implements TransactionInfoAdapter.Listener {
private TransactionInfoAdapter adapter; private TransactionInfoAdapter adapter;
private final NumberFormat formatter = NumberFormat.getInstance(); private final NumberFormat formatter = NumberFormat.getInstance();
@@ -113,15 +112,15 @@ public class WalletFragment extends Fragment
flExchange = view.findViewById(R.id.flExchange); flExchange = view.findViewById(R.id.flExchange);
((ProgressBar) view.findViewById(R.id.pbExchange)).getIndeterminateDrawable(). ((ProgressBar) view.findViewById(R.id.pbExchange)).getIndeterminateDrawable().
setColorFilter( setColorFilter(
ThemeHelper.getThemedColor(getContext(), R.attr.colorPrimaryVariant), ThemeHelper.getThemedColor(getContext(), com.google.android.material.R.attr.colorPrimaryVariant),
android.graphics.PorterDuff.Mode.MULTIPLY); android.graphics.PorterDuff.Mode.MULTIPLY);
tvProgress = view.findViewById(R.id.tvProgress); tvProgress = view.findViewById(R.id.tvProgress);
pbProgress = view.findViewById(R.id.pbProgress); pbProgress = view.findViewById(R.id.pbProgress);
tvBalance = view.findViewById(R.id.tvBalance); tvBalance = view.findViewById(R.id.tvBalance);
showBalance(Helper.getDisplayAmount(0)); showBalance();
tvUnconfirmedAmount = view.findViewById(R.id.tvUnconfirmedAmount); tvUnconfirmedAmount = view.findViewById(R.id.tvUnconfirmedAmount);
showUnconfirmed(0); showUnconfirmed();
ivSynced = view.findViewById(R.id.ivSynced); ivSynced = view.findViewById(R.id.ivSynced);
sCurrency = view.findViewById(R.id.sCurrency); sCurrency = view.findViewById(R.id.sCurrency);
@@ -204,14 +203,20 @@ public class WalletFragment extends Fragment
@Override @Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
postponeEnterTransition();
view.getViewTreeObserver().addOnPreDrawListener(() -> {
startPostponedEnterTransition();
return true;
});
} }
void showBalance(String balance) { String amountToString(double amount) {
if (!Helper.BASE_CRYPTO.equals(balanceCurrency)) { // not XMR
double amountB = amount * balanceRate;
return Helper.getFormattedAmount(amountB, false);
} else { // XMR
return Helper.getFormattedAmount(amount, true);
}
}
void showBalance() {
double amountA = Helper.getDecimalAmount(unlockedBalance).doubleValue();
String balance = amountToString(amountA);
tvBalance.setText(balance); tvBalance.setText(balance);
final boolean streetMode = activityCallback.isStreetMode(); final boolean streetMode = activityCallback.isStreetMode();
if (!streetMode) { if (!streetMode) {
@@ -224,13 +229,14 @@ public class WalletFragment extends Fragment
setStreetModeBackground(streetMode); setStreetModeBackground(streetMode);
} }
void showUnconfirmed(double unconfirmedAmount) { void showUnconfirmed() {
double unconfirmedAmount = Helper.getDecimalAmount(balance - unlockedBalance).doubleValue();
if (activityCallback.isStreetMode() || unconfirmedAmount == 0) { if (activityCallback.isStreetMode() || unconfirmedAmount == 0) {
tvUnconfirmedAmount.setText(null); tvUnconfirmedAmount.setText(null);
tvUnconfirmedAmount.setVisibility(View.GONE); tvUnconfirmedAmount.setVisibility(View.GONE);
} else { } else {
String unconfirmed = Helper.getFormattedAmount(unconfirmedAmount, true); String unconfirmed = amountToString(unconfirmedAmount);
tvUnconfirmedAmount.setText(getResources().getString(R.string.xmr_unconfirmed_amount, unconfirmed)); tvUnconfirmedAmount.setText(getResources().getString(R.string.xmr_unconfirmed_amount, unconfirmed, balanceCurrency));
tvUnconfirmedAmount.setVisibility(View.VISIBLE); tvUnconfirmedAmount.setVisibility(View.VISIBLE);
} }
} }
@@ -238,15 +244,8 @@ public class WalletFragment extends Fragment
void updateBalance() { void updateBalance() {
if (isExchanging) return; // wait for exchange to finish - it will fire this itself then. if (isExchanging) return; // wait for exchange to finish - it will fire this itself then.
// at this point selection is XMR in case of error // at this point selection is XMR in case of error
String displayB; showBalance();
double amountA = Helper.getDecimalAmount(unlockedBalance).doubleValue(); showUnconfirmed();
if (!Helper.BASE_CRYPTO.equals(balanceCurrency)) { // not XMR
double amountB = amountA * balanceRate;
displayB = Helper.getFormattedAmount(amountB, false);
} else { // XMR
displayB = Helper.getFormattedAmount(amountA, true);
}
showBalance(displayB);
} }
String balanceCurrency = Helper.BASE_CRYPTO; String balanceCurrency = Helper.BASE_CRYPTO;
@@ -255,11 +254,11 @@ public class WalletFragment extends Fragment
private final ExchangeApi exchangeApi = ServiceHelper.getExchangeApi(); private final ExchangeApi exchangeApi = ServiceHelper.getExchangeApi();
void refreshBalance() { void refreshBalance() {
double unconfirmedXmr = Helper.getDecimalAmount(balance - unlockedBalance).doubleValue();
showUnconfirmed(unconfirmedXmr);
if (sCurrency.getSelectedItemPosition() == 0) { // XMR if (sCurrency.getSelectedItemPosition() == 0) { // XMR
double amountXmr = Helper.getDecimalAmount(unlockedBalance).doubleValue(); balanceCurrency = Helper.BASE_CRYPTO;
showBalance(Helper.getFormattedAmount(amountXmr, true)); balanceRate = 1.0;
showBalance();
showUnconfirmed();
} else { // not XMR } else { // not XMR
String currency = (String) sCurrency.getSelectedItem(); String currency = (String) sCurrency.getSelectedItem();
Timber.d(currency); Timber.d(currency);
@@ -304,8 +303,7 @@ public class WalletFragment extends Fragment
public void exchangeFailed() { public void exchangeFailed() {
sCurrency.setSelection(0, true); // default to XMR sCurrency.setSelection(0, true); // default to XMR
double amountXmr = Helper.getDecimalAmount(unlockedBalance).doubleValue(); showBalance();
showBalance(Helper.getFormattedAmount(amountXmr, true));
hideExchanging(); hideExchanging();
} }
@@ -333,19 +331,9 @@ public class WalletFragment extends Fragment
// Callbacks from TransactionInfoAdapter // Callbacks from TransactionInfoAdapter
@Override @Override
public void onInteraction(final View view, final TransactionInfo infoItem) { public void onInteraction(final View view, final TransactionInfo infoItem) {
final MaterialElevationScale exitTransition = new MaterialElevationScale(false);
exitTransition.setDuration(getResources().getInteger(R.integer.tx_item_transition_duration));
setExitTransition(exitTransition);
final MaterialElevationScale reenterTransition = new MaterialElevationScale(true);
reenterTransition.setDuration(getResources().getInteger(R.integer.tx_item_transition_duration));
setReenterTransition(reenterTransition);
activityCallback.onTxDetailsRequest(view, infoItem); activityCallback.onTxDetailsRequest(view, infoItem);
} }
// called from activity
// if account index has changed scroll to top? // if account index has changed scroll to top?
private int accountIndex = 0; private int accountIndex = 0;
@@ -459,12 +447,13 @@ public class WalletFragment extends Fragment
String sync; String sync;
if (!activityCallback.hasBoundService()) if (!activityCallback.hasBoundService())
throw new IllegalStateException("WalletService not bound."); throw new IllegalStateException("WalletService not bound.");
ivSynced.setVisibility(View.GONE);
Wallet.ConnectionStatus daemonConnected = activityCallback.getConnectionStatus(); Wallet.ConnectionStatus daemonConnected = activityCallback.getConnectionStatus();
if (daemonConnected == Wallet.ConnectionStatus.ConnectionStatus_Connected) { if (daemonConnected == Wallet.ConnectionStatus.ConnectionStatus_Connected) {
if (!wallet.isSynchronized()) { if (!wallet.isSynchronized()) {
long daemonHeight = activityCallback.getDaemonHeight(); final long daemonHeight = getDaemonHeight();
long walletHeight = wallet.getBlockChainHeight(); final long walletHeight = wallet.getBlockChainHeight();
long n = daemonHeight - walletHeight; final long n = daemonHeight - walletHeight;
sync = getString(R.string.status_syncing) + " " + formatter.format(n) + " " + getString(R.string.status_remaining); sync = getString(R.string.status_syncing) + " " + formatter.format(n) + " " + getString(R.string.status_remaining);
if (firstBlock == 0) { if (firstBlock == 0) {
firstBlock = walletHeight; firstBlock = walletHeight;
@@ -472,7 +461,6 @@ public class WalletFragment extends Fragment
int x = 100 - Math.round(100f * n / (1f * daemonHeight - firstBlock)); int x = 100 - Math.round(100f * n / (1f * daemonHeight - firstBlock));
if (x == 0) x = 101; // indeterminate if (x == 0) x = 101; // indeterminate
setProgress(x); setProgress(x);
ivSynced.setVisibility(View.GONE);
} else { } else {
sync = getString(R.string.status_synced) + " " + formatter.format(wallet.getBlockChainHeight()); sync = getString(R.string.status_synced) + " " + formatter.format(wallet.getBlockChainHeight());
ivSynced.setVisibility(View.VISIBLE); ivSynced.setVisibility(View.VISIBLE);
@@ -538,8 +526,6 @@ public class WalletFragment extends Fragment
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
setExitTransition(null);
setReenterTransition(null);
Timber.d("onResume()"); Timber.d("onResume()");
activityCallback.setTitle(walletTitle, walletSubtitle); activityCallback.setTitle(walletTitle, walletSubtitle);
activityCallback.setToolbarButton(Toolbar.BUTTON_NONE); activityCallback.setToolbarButton(Toolbar.BUTTON_NONE);
@@ -574,4 +560,9 @@ public class WalletFragment extends Fragment
} else } else
ivStreetGunther.setImageDrawable(null); ivStreetGunther.setImageDrawable(null);
} }
@Override
public long getDaemonHeight() {
return activityCallback.getDaemonHeight();
}
} }

View File

@@ -22,18 +22,24 @@ import android.content.res.Configuration;
import android.os.Build; import android.os.Build;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.OptIn;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStateManagerControl;
import com.m2049r.xmrwallet.model.NetworkType; import com.m2049r.xmrwallet.model.NetworkType;
import com.m2049r.xmrwallet.util.LocaleHelper; import com.m2049r.xmrwallet.util.LocaleHelper;
import com.m2049r.xmrwallet.util.NetCipherHelper; import com.m2049r.xmrwallet.util.NetCipherHelper;
import com.m2049r.xmrwallet.util.NightmodeHelper; import com.m2049r.xmrwallet.util.NightmodeHelper;
import com.m2049r.xmrwallet.util.ServiceHelper;
import java.util.Arrays;
import timber.log.Timber; import timber.log.Timber;
public class XmrWalletApplication extends Application { public class XmrWalletApplication extends Application {
@Override @Override
@OptIn(markerClass = FragmentStateManagerControl.class)
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
FragmentManager.enableNewStateManager(false); FragmentManager.enableNewStateManager(false);

View File

@@ -21,8 +21,6 @@ import android.text.Html;
import android.text.Spanned; import android.text.Spanned;
import android.widget.TextView; import android.widget.TextView;
import androidx.core.content.ContextCompat;
import com.m2049r.levin.scanner.LevinPeer; import com.m2049r.levin.scanner.LevinPeer;
import com.m2049r.xmrwallet.R; import com.m2049r.xmrwallet.R;
import com.m2049r.xmrwallet.util.NetCipherHelper; import com.m2049r.xmrwallet.util.NetCipherHelper;
@@ -272,7 +270,7 @@ public class NodeInfo extends Node {
(hostAddress.isOnion() ? "&nbsp;.onion&nbsp;&nbsp;" : ""), " " + info)); (hostAddress.isOnion() ? "&nbsp;.onion&nbsp;&nbsp;" : ""), " " + info));
view.setText(text); view.setText(text);
if (isError) if (isError)
view.setTextColor(ThemeHelper.getThemedColor(ctx, R.attr.colorError)); view.setTextColor(ThemeHelper.getThemedColor(ctx, androidx.appcompat.R.attr.colorError));
else else
view.setTextColor(ThemeHelper.getThemedColor(ctx, android.R.attr.textColorSecondary)); view.setTextColor(ThemeHelper.getThemedColor(ctx, android.R.attr.textColorSecondary));
} }

File diff suppressed because it is too large Load Diff

View File

@@ -41,10 +41,6 @@ public class TxDataBtc extends TxData {
super(); super();
} }
public TxDataBtc(TxDataBtc txDataBtc) {
super(txDataBtc);
}
@Override @Override
public void writeToParcel(Parcel out, int flags) { public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags); super.writeToParcel(out, flags);

View File

@@ -19,15 +19,16 @@ package com.m2049r.xmrwallet.dialog;
import android.app.Dialog; import android.app.Dialog;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.os.Bundle; import android.os.Bundle;
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.text.Html;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.widget.TextView; 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.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.m2049r.xmrwallet.BuildConfig; import com.m2049r.xmrwallet.BuildConfig;
import com.m2049r.xmrwallet.R; import com.m2049r.xmrwallet.R;

View File

@@ -0,0 +1,133 @@
/*
* Copyright (c) 2023 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.dialog;
import android.app.Dialog;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.slider.Slider;
import com.google.android.material.switchmaterial.SwitchMaterial;
import com.m2049r.xmrwallet.R;
import com.m2049r.xmrwallet.model.Wallet;
import com.m2049r.xmrwallet.util.Helper;
public class PocketChangeFragment extends DialogFragment implements Slider.OnChangeListener {
static final String TAG = "PocketChangeFragment";
static final String ENABLED = "enabled";
static final String TICK = "tick";
public static PocketChangeFragment newInstance(boolean enabled, int tick) {
PocketChangeFragment fragment = new PocketChangeFragment();
Bundle bundle = new Bundle();
bundle.putInt(ENABLED, enabled ? 1 : 0);
bundle.putInt(TICK, tick);
fragment.setArguments(bundle);
return fragment;
}
public static void display(FragmentManager fm, @NonNull Wallet.PocketChangeSetting setting) {
FragmentTransaction ft = fm.beginTransaction();
Fragment prev = fm.findFragmentByTag(TAG);
if (prev != null) {
ft.remove(prev);
}
PocketChangeFragment.newInstance(setting.isEnabled(), getTick(setting.getAmount())).show(ft, TAG);
}
SwitchMaterial switchPocketChange;
Slider slider;
TextView tvProgressLabel;
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_pocketchange_setting, null);
boolean enabled = false;
int progress = 0;
Bundle arguments = getArguments();
if (arguments != null) {
enabled = arguments.getInt(ENABLED) > 0;
progress = arguments.getInt(TICK);
}
final View llAmount = view.findViewById(R.id.llAmount);
switchPocketChange = view.findViewById(R.id.switchPocketChange);
switchPocketChange.setOnCheckedChangeListener((buttonView, isChecked) -> llAmount.setVisibility(isChecked ? View.VISIBLE : View.INVISIBLE));
slider = view.findViewById(R.id.seekbar);
slider.addOnChangeListener(this);
switchPocketChange.setChecked(enabled);
tvProgressLabel = view.findViewById(R.id.seekbar_value);
slider.setValue(progress);
llAmount.setVisibility(enabled ? View.VISIBLE : View.INVISIBLE);
onValueChange(slider, slider.getValue(), false);
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity())
.setView(view)
.setPositiveButton(R.string.label_apply,
(dialog, whichButton) -> {
final FragmentActivity activity = getActivity();
if (activity instanceof Listener) {
((Listener) activity).setPocketChange(Wallet.PocketChangeSetting.of(switchPocketChange.isChecked(), getAmount()));
}
}
);
return builder.create();
}
private long getAmount() {
return Wallet.getAmountFromDouble(getAmount((int) slider.getValue()));
}
private static final double[] AMOUNTS = {0.1, 0.2, 0.3, 0.5, 0.8, 1.3};
private static double getAmount(int i) {
return AMOUNTS[i];
}
// find the closest amount we have
private static int getTick(long amount) {
int enabled = amount > 0 ? 1 : -1;
amount = Math.abs(amount);
double lastDiff = Double.MAX_VALUE;
for (int i = 0; i < AMOUNTS.length; i++) {
final double diff = Math.abs(Helper.ONE_XMR * AMOUNTS[i] - amount);
if (lastDiff < diff) return i - 1;
lastDiff = diff;
}
return enabled * (AMOUNTS.length - 1);
}
@Override
public void onValueChange(@NonNull Slider slider, float value, boolean fromUser) {
tvProgressLabel.setText(getString(R.string.pocketchange_amount, getAmount((int) value)));
}
public interface Listener {
void setPocketChange(Wallet.PocketChangeSetting setting);
}
}

View File

@@ -17,12 +17,10 @@
package com.m2049r.xmrwallet.fragment.send; package com.m2049r.xmrwallet.fragment.send;
import android.content.Context; import android.content.Context;
import android.nfc.NfcManager;
import android.os.Bundle; import android.os.Bundle;
import android.text.Editable; import android.text.Editable;
import android.text.Html; import android.text.Html;
import android.text.InputType; import android.text.InputType;
import android.text.Spanned;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.util.Patterns; import android.util.Patterns;
import android.view.KeyEvent; import android.view.KeyEvent;
@@ -268,11 +266,6 @@ public class SendAddressWizardFragment extends SendWizardFragment {
etDummy.setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); etDummy.setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
etDummy.requestFocus(); etDummy.requestFocus();
View tvNfc = view.findViewById(R.id.tvNfc);
NfcManager manager = (NfcManager) getContext().getSystemService(Context.NFC_SERVICE);
if ((manager != null) && (manager.getDefaultAdapter() != null))
tvNfc.setVisibility(View.VISIBLE);
return view; return view;
} }
@@ -418,10 +411,10 @@ public class SendAddressWizardFragment extends SendWizardFragment {
if (txData instanceof TxDataBtc) { if (txData instanceof TxDataBtc) {
((TxDataBtc) txData).setBtcAddress(etAddress.getEditText().getText().toString()); ((TxDataBtc) txData).setBtcAddress(etAddress.getEditText().getText().toString());
((TxDataBtc) txData).setBtcSymbol(selectedCrypto.getSymbol()); ((TxDataBtc) txData).setBtcSymbol(selectedCrypto.getSymbol());
txData.setDestinationAddress(null); txData.setDestination(null);
ServiceHelper.ASSET = selectedCrypto.getSymbol().toLowerCase(); ServiceHelper.ASSET = selectedCrypto.getSymbol().toLowerCase();
} else { } else {
txData.setDestinationAddress(etAddress.getEditText().getText().toString()); txData.setDestination(etAddress.getEditText().getText().toString());
ServiceHelper.ASSET = null; ServiceHelper.ASSET = null;
} }
txData.setUserNotes(new UserNotes(etNotes.getEditText().getText().toString())); txData.setUserNotes(new UserNotes(etNotes.getEditText().getText().toString()));

View File

@@ -23,6 +23,8 @@ import android.view.ViewGroup;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.TextView; import android.widget.TextView;
import com.google.android.material.progressindicator.LinearProgressIndicator;
import com.google.android.material.switchmaterial.SwitchMaterial;
import com.m2049r.xmrwallet.R; import com.m2049r.xmrwallet.R;
import com.m2049r.xmrwallet.data.BarcodeData; import com.m2049r.xmrwallet.data.BarcodeData;
import com.m2049r.xmrwallet.data.TxData; import com.m2049r.xmrwallet.data.TxData;

View File

@@ -74,6 +74,9 @@ public class SendBtcConfirmWizardFragment extends SendWizardFragment implements
private View llConfirmSend; private View llConfirmSend;
private Button bSend; private Button bSend;
private View pbProgressSend; private View pbProgressSend;
private TextView tvTxChange;
private View llPocketChange;
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
@@ -92,6 +95,8 @@ public class SendBtcConfirmWizardFragment extends SendWizardFragment implements
tvTxFee = view.findViewById(R.id.tvTxFee); tvTxFee = view.findViewById(R.id.tvTxFee);
tvTxTotal = view.findViewById(R.id.tvTxTotal); tvTxTotal = view.findViewById(R.id.tvTxTotal);
tvTxChange = view.findViewById(R.id.tvTxChange);
llPocketChange = view.findViewById(R.id.llPocketChange);
llStageA = view.findViewById(R.id.llStageA); llStageA = view.findViewById(R.id.llStageA);
evStageA = view.findViewById(R.id.evStageA); evStageA = view.findViewById(R.id.evStageA);
@@ -217,6 +222,13 @@ public class SendBtcConfirmWizardFragment extends SendWizardFragment implements
tvTxFee.setText(Wallet.getDisplayAmount(pendingTransaction.getFee())); tvTxFee.setText(Wallet.getDisplayAmount(pendingTransaction.getFee()));
tvTxTotal.setText(Wallet.getDisplayAmount( tvTxTotal.setText(Wallet.getDisplayAmount(
pendingTransaction.getFee() + pendingTransaction.getAmount())); pendingTransaction.getFee() + pendingTransaction.getAmount()));
final long change = pendingTransaction.getPocketChange();
if (change > 0) {
llPocketChange.setVisibility(View.VISIBLE);
tvTxChange.setText(Wallet.getDisplayAmount(change));
} else {
llPocketChange.setVisibility(View.GONE);
}
updateSendButton(); updateSendButton();
}); });
} else { } else {
@@ -348,7 +360,7 @@ public class SendBtcConfirmWizardFragment extends SendWizardFragment implements
} }
showProgress(3, getString(R.string.label_send_progress_create_tx)); showProgress(3, getString(R.string.label_send_progress_create_tx));
final TxData txData = sendListener.getTxData(); final TxData txData = sendListener.getTxData();
txData.setDestinationAddress(xmrtoOrder.getXmrAddress()); txData.setDestination(xmrtoOrder.getXmrAddress());
txData.setAmount(xmrtoOrder.getXmrAmount()); txData.setAmount(xmrtoOrder.getXmrAmount());
getActivityCallback().onPrepareSend(xmrtoOrder.getOrderId(), txData); getActivityCallback().onPrepareSend(xmrtoOrder.getOrderId(), txData);
} }

View File

@@ -140,7 +140,7 @@ public class SendBtcSuccessWizardFragment extends SendWizardFragment {
isResumed = true; isResumed = true;
btcData = (TxDataBtc) sendListener.getTxData(); btcData = (TxDataBtc) sendListener.getTxData();
tvTxAddress.setText(btcData.getDestinationAddress()); tvTxAddress.setText(btcData.getDestination());
final PendingTx committedTx = sendListener.getCommittedTx(); final PendingTx committedTx = sendListener.getCommittedTx();
if (committedTx != null) { if (committedTx != null) {

View File

@@ -17,9 +17,6 @@
package com.m2049r.xmrwallet.fragment.send; package com.m2049r.xmrwallet.fragment.send;
import android.os.Bundle; import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@@ -28,7 +25,6 @@ import android.widget.TextView;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.textfield.TextInputLayout;
import com.m2049r.xmrwallet.R; import com.m2049r.xmrwallet.R;
import com.m2049r.xmrwallet.data.TxData; import com.m2049r.xmrwallet.data.TxData;
import com.m2049r.xmrwallet.data.UserNotes; import com.m2049r.xmrwallet.data.UserNotes;
@@ -68,12 +64,14 @@ public class SendConfirmWizardFragment extends SendWizardFragment implements Sen
private TextView tvTxAddress; private TextView tvTxAddress;
private TextView tvTxNotes; private TextView tvTxNotes;
private TextView tvTxAmount; private TextView tvTxAmount;
private TextView tvTxChange;
private TextView tvTxFee; private TextView tvTxFee;
private TextView tvTxTotal; private TextView tvTxTotal;
private View llProgress; private View llProgress;
private View bSend; private View bSend;
private View llConfirmSend; private View llConfirmSend;
private View pbProgressSend; private View pbProgressSend;
private View llPocketChange;
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
@@ -87,12 +85,14 @@ public class SendConfirmWizardFragment extends SendWizardFragment implements Sen
tvTxAddress = view.findViewById(R.id.tvTxAddress); tvTxAddress = view.findViewById(R.id.tvTxAddress);
tvTxNotes = view.findViewById(R.id.tvTxNotes); tvTxNotes = view.findViewById(R.id.tvTxNotes);
tvTxAmount = view.findViewById(R.id.tvTxAmount); tvTxAmount = view.findViewById(R.id.tvTxAmount);
tvTxChange = view.findViewById(R.id.tvTxChange);
tvTxFee = view.findViewById(R.id.tvTxFee); tvTxFee = view.findViewById(R.id.tvTxFee);
tvTxTotal = view.findViewById(R.id.tvTxTotal); tvTxTotal = view.findViewById(R.id.tvTxTotal);
llProgress = view.findViewById(R.id.llProgress); llProgress = view.findViewById(R.id.llProgress);
pbProgressSend = view.findViewById(R.id.pbProgressSend); pbProgressSend = view.findViewById(R.id.pbProgressSend);
llConfirmSend = view.findViewById(R.id.llConfirmSend); llConfirmSend = view.findViewById(R.id.llConfirmSend);
llPocketChange = view.findViewById(R.id.llPocketChange);
bSend = view.findViewById(R.id.bSend); bSend = view.findViewById(R.id.bSend);
bSend.setEnabled(false); bSend.setEnabled(false);
@@ -185,7 +185,7 @@ public class SendConfirmWizardFragment extends SendWizardFragment implements Sen
isResumed = true; isResumed = true;
final TxData txData = sendListener.getTxData(); final TxData txData = sendListener.getTxData();
tvTxAddress.setText(txData.getDestinationAddress()); tvTxAddress.setText(txData.getDestination());
UserNotes notes = sendListener.getTxData().getUserNotes(); UserNotes notes = sendListener.getTxData().getUserNotes();
if ((notes != null) && (!notes.note.isEmpty())) { if ((notes != null) && (!notes.note.isEmpty())) {
tvTxNotes.setText(notes.note); tvTxNotes.setText(notes.note);
@@ -210,7 +210,14 @@ public class SendConfirmWizardFragment extends SendWizardFragment implements Sen
tvTxAmount.setText(getString(R.string.street_sweep_amount)); tvTxAmount.setText(getString(R.string.street_sweep_amount));
tvTxTotal.setText(getString(R.string.street_sweep_amount)); tvTxTotal.setText(getString(R.string.street_sweep_amount));
} else { } else {
tvTxAmount.setText(Wallet.getDisplayAmount(pendingTransaction.getAmount())); tvTxAmount.setText(Wallet.getDisplayAmount(pendingTransaction.getNetAmount()));
final long change = pendingTransaction.getPocketChange();
if (change > 0) {
llPocketChange.setVisibility(View.VISIBLE);
tvTxChange.setText(Wallet.getDisplayAmount(change));
} else {
llPocketChange.setVisibility(View.GONE);
}
tvTxTotal.setText(Wallet.getDisplayAmount( tvTxTotal.setText(Wallet.getDisplayAmount(
pendingTransaction.getFee() + pendingTransaction.getAmount())); pendingTransaction.getFee() + pendingTransaction.getAmount()));
} }

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