mirror of
https://github.com/m2049r/xmrwallet
synced 2025-09-02 15:53:04 +02:00
Compare commits
31 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b01de1ad6e | ||
![]() |
5fb1bcb552 | ||
![]() |
b937ba38b6 | ||
![]() |
849718fdc7 | ||
![]() |
a6372f701d | ||
![]() |
12f135bb14 | ||
![]() |
16870fcbb9 | ||
![]() |
2fbd152fb3 | ||
![]() |
a7b178e024 | ||
![]() |
c5a035437b | ||
![]() |
75c550fd19 | ||
![]() |
1b680344b1 | ||
![]() |
3329636d32 | ||
![]() |
77e9bf7c43 | ||
![]() |
40f5c9365e | ||
![]() |
850ba7efef | ||
![]() |
548369ca0b | ||
![]() |
afc0d5b7bc | ||
![]() |
02e92db59a | ||
![]() |
2b34454214 | ||
![]() |
12706119d3 | ||
![]() |
f7a762f32b | ||
![]() |
86d5d2a2cb | ||
![]() |
e56369b91a | ||
![]() |
b04aa24269 | ||
![]() |
dda86bd5de | ||
![]() |
a19ad7fd52 | ||
![]() |
0443fd808c | ||
![]() |
faf57c96fc | ||
![]() |
57ddddfce2 | ||
![]() |
ab6069058b |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -15,3 +15,4 @@
|
||||
/app/alphaStagenet
|
||||
/app/prodStagenet
|
||||
/app/.cxx
|
||||
/monerujo.id
|
||||
|
@@ -13,7 +13,7 @@ set(EXTERNAL_LIBS_DIR ${CMAKE_SOURCE_DIR}/../external-libs)
|
||||
|
||||
add_library(sodium STATIC IMPORTED)
|
||||
set_target_properties(sodium PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/libsodium/lib/${ANDROID_ABI}/libsodium.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libsodium.a)
|
||||
|
||||
############
|
||||
# OpenSSL
|
||||
@@ -21,11 +21,11 @@ set_target_properties(sodium PROPERTIES IMPORTED_LOCATION
|
||||
|
||||
add_library(crypto STATIC IMPORTED)
|
||||
set_target_properties(crypto PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/openssl/lib/${ANDROID_ABI}/libcrypto.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libcrypto.a)
|
||||
|
||||
add_library(ssl STATIC IMPORTED)
|
||||
set_target_properties(ssl PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/openssl/lib/${ANDROID_ABI}/libssl.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libssl.a)
|
||||
|
||||
############
|
||||
# Boost
|
||||
@@ -33,39 +33,39 @@ set_target_properties(ssl PROPERTIES IMPORTED_LOCATION
|
||||
|
||||
add_library(boost_chrono STATIC IMPORTED)
|
||||
set_target_properties(boost_chrono PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_chrono.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libboost_chrono.a)
|
||||
|
||||
add_library(boost_date_time STATIC IMPORTED)
|
||||
set_target_properties(boost_date_time PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_date_time.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libboost_date_time.a)
|
||||
|
||||
add_library(boost_filesystem STATIC IMPORTED)
|
||||
set_target_properties(boost_filesystem PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_filesystem.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libboost_filesystem.a)
|
||||
|
||||
add_library(boost_program_options STATIC IMPORTED)
|
||||
set_target_properties(boost_program_options PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_program_options.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libboost_program_options.a)
|
||||
|
||||
add_library(boost_regex STATIC IMPORTED)
|
||||
set_target_properties(boost_regex PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_regex.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libboost_regex.a)
|
||||
|
||||
add_library(boost_serialization STATIC IMPORTED)
|
||||
set_target_properties(boost_serialization PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_serialization.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libboost_serialization.a)
|
||||
|
||||
add_library(boost_system STATIC IMPORTED)
|
||||
set_target_properties(boost_system PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_system.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libboost_system.a)
|
||||
|
||||
add_library(boost_thread STATIC IMPORTED)
|
||||
set_target_properties(boost_thread PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_thread.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libboost_thread.a)
|
||||
|
||||
add_library(boost_wserialization STATIC IMPORTED)
|
||||
set_target_properties(boost_wserialization PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/boost/lib/${ANDROID_ABI}/libboost_wserialization.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/libboost_wserialization.a)
|
||||
|
||||
#############
|
||||
# Monero
|
||||
@@ -73,99 +73,103 @@ set_target_properties(boost_wserialization PROPERTIES IMPORTED_LOCATION
|
||||
|
||||
add_library(wallet_api STATIC IMPORTED)
|
||||
set_target_properties(wallet_api PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libwallet_api.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libwallet_api.a)
|
||||
|
||||
add_library(wallet STATIC IMPORTED)
|
||||
set_target_properties(wallet PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libwallet.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libwallet.a)
|
||||
|
||||
add_library(cryptonote_core STATIC IMPORTED)
|
||||
set_target_properties(cryptonote_core PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libcryptonote_core.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libcryptonote_core.a)
|
||||
|
||||
add_library(cryptonote_basic STATIC IMPORTED)
|
||||
set_target_properties(cryptonote_basic PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libcryptonote_basic.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libcryptonote_basic.a)
|
||||
|
||||
add_library(mnemonics STATIC IMPORTED)
|
||||
set_target_properties(mnemonics PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libmnemonics.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libmnemonics.a)
|
||||
|
||||
add_library(common STATIC IMPORTED)
|
||||
set_target_properties(common PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libcommon.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libcommon.a)
|
||||
|
||||
add_library(cncrypto STATIC IMPORTED)
|
||||
set_target_properties(cncrypto PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libcncrypto.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libcncrypto.a)
|
||||
|
||||
add_library(ringct STATIC IMPORTED)
|
||||
set_target_properties(ringct PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libringct.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libringct.a)
|
||||
|
||||
add_library(ringct_basic STATIC IMPORTED)
|
||||
set_target_properties(ringct_basic PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libringct_basic.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libringct_basic.a)
|
||||
|
||||
add_library(blockchain_db STATIC IMPORTED)
|
||||
set_target_properties(blockchain_db PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libblockchain_db.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libblockchain_db.a)
|
||||
|
||||
add_library(lmdb STATIC IMPORTED)
|
||||
set_target_properties(lmdb PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/liblmdb.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/liblmdb.a)
|
||||
|
||||
add_library(easylogging STATIC IMPORTED)
|
||||
set_target_properties(easylogging PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libeasylogging.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libeasylogging.a)
|
||||
|
||||
add_library(unbound STATIC IMPORTED)
|
||||
set_target_properties(unbound PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libunbound.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libunbound.a)
|
||||
|
||||
add_library(epee STATIC IMPORTED)
|
||||
set_target_properties(epee PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libepee.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libepee.a)
|
||||
|
||||
add_library(blocks STATIC IMPORTED)
|
||||
set_target_properties(blocks PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libblocks.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libblocks.a)
|
||||
|
||||
add_library(checkpoints STATIC IMPORTED)
|
||||
set_target_properties(checkpoints PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libcheckpoints.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libcheckpoints.a)
|
||||
|
||||
add_library(device STATIC IMPORTED)
|
||||
set_target_properties(device PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libdevice.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libdevice.a)
|
||||
|
||||
add_library(device_trezor STATIC IMPORTED)
|
||||
set_target_properties(device_trezor PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libdevice_trezor.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libdevice_trezor.a)
|
||||
|
||||
add_library(multisig STATIC IMPORTED)
|
||||
set_target_properties(multisig PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libmultisig.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libmultisig.a)
|
||||
|
||||
add_library(version STATIC IMPORTED)
|
||||
set_target_properties(version PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libversion.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libversion.a)
|
||||
|
||||
add_library(net STATIC IMPORTED)
|
||||
set_target_properties(net PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libnet.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libnet.a)
|
||||
|
||||
add_library(hardforks STATIC IMPORTED)
|
||||
set_target_properties(hardforks PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/libhardforks.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libhardforks.a)
|
||||
|
||||
add_library(randomx STATIC IMPORTED)
|
||||
set_target_properties(randomx PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/librandomx.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/librandomx.a)
|
||||
|
||||
add_library(rpc_base STATIC IMPORTED)
|
||||
set_target_properties(rpc_base PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/monero/lib/${ANDROID_ABI}/librpc_base.a)
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/librpc_base.a)
|
||||
|
||||
add_library(wallet-crypto STATIC IMPORTED)
|
||||
set_target_properties(wallet-crypto PROPERTIES IMPORTED_LOCATION
|
||||
${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libwallet-crypto.a)
|
||||
|
||||
#############
|
||||
# System
|
||||
@@ -173,10 +177,16 @@ set_target_properties(rpc_base PROPERTIES IMPORTED_LOCATION
|
||||
|
||||
find_library( log-lib log )
|
||||
|
||||
include_directories( ${EXTERNAL_LIBS_DIR}/monero/include )
|
||||
include_directories( ${EXTERNAL_LIBS_DIR}/include )
|
||||
|
||||
message(STATUS EXTERNAL_LIBS_DIR : ${EXTERNAL_LIBS_DIR})
|
||||
|
||||
if(${ANDROID_ABI} STREQUAL "x86_64")
|
||||
set(EXTRA_LIBS "wallet-crypto")
|
||||
else()
|
||||
set(EXTRA_LIBS "")
|
||||
endif()
|
||||
|
||||
target_link_libraries( monerujo
|
||||
|
||||
wallet_api
|
||||
@@ -203,6 +213,7 @@ target_link_libraries( monerujo
|
||||
randomx
|
||||
hardforks
|
||||
rpc_base
|
||||
${EXTRA_LIBS}
|
||||
|
||||
boost_chrono
|
||||
boost_date_time
|
||||
|
@@ -2,13 +2,13 @@ apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 29
|
||||
buildToolsVersion '29.0.2'
|
||||
buildToolsVersion '29.0.3'
|
||||
defaultConfig {
|
||||
applicationId "com.m2049r.xmrwallet"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 29
|
||||
versionCode 602
|
||||
versionName "1.16.2 'Karmic Nodes'"
|
||||
versionCode 713
|
||||
versionName "1.17.13 'Druk'"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
@@ -56,6 +56,9 @@ android {
|
||||
debug {
|
||||
applicationIdSuffix ".debug"
|
||||
}
|
||||
applicationVariants.all { variant ->
|
||||
variant.buildConfigField "String", "ID_A", "\"" + getId("ID_A") + "\""
|
||||
}
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
@@ -109,10 +112,16 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
def getId(name) {
|
||||
def Properties props = new Properties()
|
||||
props.load(new FileInputStream(new File('monerujo.id')))
|
||||
return props[name]
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'androidx.core:core:1.3.2'
|
||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||
implementation 'com.google.android.material:material:1.3.0-alpha03'
|
||||
implementation 'com.google.android.material:material:1.3.0'
|
||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.1.0'
|
||||
implementation 'androidx.cardview:cardview:1.0.0'
|
||||
|
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2018 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.levin.scanner;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020 m2049r et al.
|
||||
*
|
||||
* 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.app.PendingIntent;
|
||||
@@ -197,7 +213,7 @@ public class BaseActivity extends SecureActivity implements GenerateReviewFragme
|
||||
if (uri == null) {
|
||||
Toast.makeText(this, getString(R.string.nfc_tag_read_undef), Toast.LENGTH_LONG).show();
|
||||
} else {
|
||||
BarcodeData bc = BarcodeData.fromQrCode(uri.toString());
|
||||
BarcodeData bc = BarcodeData.fromString(uri.toString());
|
||||
if (bc == null)
|
||||
Toast.makeText(this, getString(R.string.nfc_tag_read_undef), Toast.LENGTH_LONG).show();
|
||||
else
|
||||
|
@@ -50,9 +50,8 @@ import com.m2049r.xmrwallet.util.Helper;
|
||||
import com.m2049r.xmrwallet.util.KeyStoreHelper;
|
||||
import com.m2049r.xmrwallet.util.RestoreHeight;
|
||||
import com.m2049r.xmrwallet.util.ledger.Monero;
|
||||
import com.m2049r.xmrwallet.widget.PasswordEntryView;
|
||||
import com.m2049r.xmrwallet.widget.Toolbar;
|
||||
import com.nulabinc.zxcvbn.Strength;
|
||||
import com.nulabinc.zxcvbn.Zxcvbn;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.ParseException;
|
||||
@@ -70,7 +69,7 @@ public class GenerateFragment extends Fragment {
|
||||
static final String TYPE_VIEWONLY = "view";
|
||||
|
||||
private TextInputLayout etWalletName;
|
||||
private TextInputLayout etWalletPassword;
|
||||
private PasswordEntryView etWalletPassword;
|
||||
private LinearLayout llFingerprintAuth;
|
||||
private TextInputLayout etWalletAddress;
|
||||
private TextInputLayout etWalletMnemonic;
|
||||
@@ -131,21 +130,6 @@ public class GenerateFragment extends Fragment {
|
||||
});
|
||||
clearErrorOnTextEntry(etWalletName);
|
||||
|
||||
etWalletPassword.getEditText().addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable) {
|
||||
checkPassword();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
});
|
||||
|
||||
etWalletMnemonic.getEditText().setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
||||
@Override
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
@@ -354,45 +338,10 @@ public class GenerateFragment extends Fragment {
|
||||
});
|
||||
|
||||
etWalletName.requestFocus();
|
||||
initZxcvbn();
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
Zxcvbn zxcvbn = new Zxcvbn();
|
||||
|
||||
// initialize zxcvbn engine in background thread
|
||||
private void initZxcvbn() {
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
zxcvbn.measure("");
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void checkPassword() {
|
||||
String password = etWalletPassword.getEditText().getText().toString();
|
||||
if (!password.isEmpty()) {
|
||||
Strength strength = zxcvbn.measure(password);
|
||||
int msg;
|
||||
double guessesLog10 = strength.getGuessesLog10();
|
||||
if (guessesLog10 < 10)
|
||||
msg = R.string.password_weak;
|
||||
else if (guessesLog10 < 11)
|
||||
msg = R.string.password_fair;
|
||||
else if (guessesLog10 < 12)
|
||||
msg = R.string.password_good;
|
||||
else if (guessesLog10 < 13)
|
||||
msg = R.string.password_strong;
|
||||
else
|
||||
msg = R.string.password_very_strong;
|
||||
etWalletPassword.setError(getResources().getString(msg));
|
||||
} else {
|
||||
etWalletPassword.setError(null);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkName() {
|
||||
String name = etWalletName.getEditText().getText().toString();
|
||||
boolean ok = true;
|
||||
@@ -429,7 +378,7 @@ public class GenerateFragment extends Fragment {
|
||||
}
|
||||
|
||||
private long getHeight() {
|
||||
long height = 0;
|
||||
long height = -1;
|
||||
|
||||
String restoreHeight = etWalletRestoreHeight.getEditText().getText().toString().trim();
|
||||
if (restoreHeight.isEmpty()) return -1;
|
||||
@@ -440,7 +389,7 @@ public class GenerateFragment extends Fragment {
|
||||
height = RestoreHeight.getInstance().getHeight(parser.parse(restoreHeight));
|
||||
} catch (ParseException ex) {
|
||||
}
|
||||
if ((height <= 0) && (restoreHeight.length() == 8))
|
||||
if ((height < 0) && (restoreHeight.length() == 8))
|
||||
try {
|
||||
// is it a date without dashes?
|
||||
SimpleDateFormat parser = new SimpleDateFormat("yyyyMMdd");
|
||||
@@ -448,7 +397,7 @@ public class GenerateFragment extends Fragment {
|
||||
height = RestoreHeight.getInstance().getHeight(parser.parse(restoreHeight));
|
||||
} catch (ParseException ex) {
|
||||
}
|
||||
if (height <= 0)
|
||||
if (height < 0)
|
||||
try {
|
||||
// or is it a height?
|
||||
height = Long.parseLong(restoreHeight);
|
||||
@@ -654,24 +603,7 @@ public class GenerateFragment extends Fragment {
|
||||
final TextInputLayout etSeed = promptsView.findViewById(R.id.etSeed);
|
||||
final TextInputLayout etPassphrase = promptsView.findViewById(R.id.etPassphrase);
|
||||
|
||||
etSeed.getEditText().addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
if (etSeed.getError() != null) {
|
||||
etSeed.setError(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start,
|
||||
int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start,
|
||||
int before, int count) {
|
||||
}
|
||||
});
|
||||
clearErrorOnTextEntry(etSeed);
|
||||
|
||||
alertDialogBuilder
|
||||
.setCancelable(false)
|
||||
|
@@ -56,6 +56,7 @@ import com.m2049r.xmrwallet.util.FingerprintHelper;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
import com.m2049r.xmrwallet.util.KeyStoreHelper;
|
||||
import com.m2049r.xmrwallet.util.MoneroThreadPoolExecutor;
|
||||
import com.m2049r.xmrwallet.widget.PasswordEntryView;
|
||||
import com.m2049r.xmrwallet.widget.Toolbar;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
@@ -473,7 +474,7 @@ public class GenerateReviewFragment extends Fragment {
|
||||
AlertDialog.Builder alertDialogBuilder = new MaterialAlertDialogBuilder(getActivity());
|
||||
alertDialogBuilder.setView(promptsView);
|
||||
|
||||
final TextInputLayout etPasswordA = promptsView.findViewById(R.id.etWalletPasswordA);
|
||||
final PasswordEntryView etPasswordA = promptsView.findViewById(R.id.etWalletPasswordA);
|
||||
etPasswordA.setHint(getString(R.string.prompt_changepw, walletName));
|
||||
|
||||
final TextInputLayout etPasswordB = promptsView.findViewById(R.id.etWalletPasswordB);
|
||||
@@ -509,9 +510,6 @@ public class GenerateReviewFragment extends Fragment {
|
||||
etPasswordA.getEditText().addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
if (etPasswordA.getError() != null) {
|
||||
etPasswordA.setError(null);
|
||||
}
|
||||
if (etPasswordB.getError() != null) {
|
||||
etPasswordB.setError(null);
|
||||
}
|
||||
@@ -531,9 +529,6 @@ public class GenerateReviewFragment extends Fragment {
|
||||
etPasswordB.getEditText().addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
if (etPasswordA.getError() != null) {
|
||||
etPasswordA.setError(null);
|
||||
}
|
||||
if (etPasswordB.getError() != null) {
|
||||
etPasswordB.setError(null);
|
||||
}
|
||||
@@ -564,29 +559,20 @@ public class GenerateReviewFragment extends Fragment {
|
||||
});
|
||||
|
||||
openDialog = alertDialogBuilder.create();
|
||||
openDialog.setOnShowListener(new DialogInterface.OnShowListener() {
|
||||
@Override
|
||||
public void onShow(final DialogInterface dialog) {
|
||||
Button button = ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE);
|
||||
button.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
String newPasswordA = etPasswordA.getEditText().getText().toString();
|
||||
String newPasswordB = etPasswordB.getEditText().getText().toString();
|
||||
// disallow empty passwords
|
||||
if (newPasswordA.isEmpty()) {
|
||||
etPasswordA.setError(getString(R.string.generate_empty_passwordB));
|
||||
} else if (!newPasswordA.equals(newPasswordB)) {
|
||||
etPasswordB.setError(getString(R.string.generate_bad_passwordB));
|
||||
} else {
|
||||
new AsyncChangePassword().execute(newPasswordA, Boolean.toString(swFingerprintAllowed.isChecked()));
|
||||
Helper.hideKeyboardAlways(getActivity());
|
||||
openDialog.dismiss();
|
||||
openDialog = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
openDialog.setOnShowListener(dialog -> {
|
||||
Button button = ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE);
|
||||
button.setOnClickListener(view -> {
|
||||
String newPasswordA = etPasswordA.getEditText().getText().toString();
|
||||
String newPasswordB = etPasswordB.getEditText().getText().toString();
|
||||
if (!newPasswordA.equals(newPasswordB)) {
|
||||
etPasswordB.setError(getString(R.string.generate_bad_passwordB));
|
||||
} else {
|
||||
new AsyncChangePassword().execute(newPasswordA, Boolean.toString(swFingerprintAllowed.isChecked()));
|
||||
Helper.hideKeyboardAlways(getActivity());
|
||||
openDialog.dismiss();
|
||||
openDialog = null;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// accept keyboard "ok"
|
||||
@@ -597,9 +583,7 @@ public class GenerateReviewFragment extends Fragment {
|
||||
String newPasswordA = etPasswordA.getEditText().getText().toString();
|
||||
String newPasswordB = etPasswordB.getEditText().getText().toString();
|
||||
// disallow empty passwords
|
||||
if (newPasswordA.isEmpty()) {
|
||||
etPasswordA.setError(getString(R.string.generate_empty_passwordB));
|
||||
} else if (!newPasswordA.equals(newPasswordB)) {
|
||||
if (!newPasswordA.equals(newPasswordB)) {
|
||||
etPasswordB.setError(getString(R.string.generate_bad_passwordB));
|
||||
} else {
|
||||
new AsyncChangePassword().execute(newPasswordA, Boolean.toString(swFingerprintAllowed.isChecked()));
|
||||
|
@@ -59,7 +59,7 @@ 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.ThemeHelper;
|
||||
import com.m2049r.xmrwallet.util.DayNightMode;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
import com.m2049r.xmrwallet.util.KeyStoreHelper;
|
||||
@@ -78,7 +78,6 @@ import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@@ -301,24 +300,21 @@ public class LoginActivity extends BaseActivity
|
||||
setSupportActionBar(toolbar);
|
||||
getSupportActionBar().setDisplayShowTitleEnabled(false);
|
||||
|
||||
toolbar.setOnButtonListener(new Toolbar.OnButtonListener() {
|
||||
@Override
|
||||
public void onButton(int type) {
|
||||
switch (type) {
|
||||
case Toolbar.BUTTON_BACK:
|
||||
onBackPressed();
|
||||
break;
|
||||
case Toolbar.BUTTON_CLOSE:
|
||||
finish();
|
||||
break;
|
||||
case Toolbar.BUTTON_CREDITS:
|
||||
CreditsFragment.display(getSupportFragmentManager());
|
||||
break;
|
||||
case Toolbar.BUTTON_NONE:
|
||||
break;
|
||||
default:
|
||||
Timber.e("Button " + type + "pressed - how can this be?");
|
||||
}
|
||||
toolbar.setOnButtonListener(type -> {
|
||||
switch (type) {
|
||||
case Toolbar.BUTTON_BACK:
|
||||
onBackPressed();
|
||||
break;
|
||||
case Toolbar.BUTTON_CLOSE:
|
||||
finish();
|
||||
break;
|
||||
case Toolbar.BUTTON_CREDITS:
|
||||
CreditsFragment.display(getSupportFragmentManager());
|
||||
break;
|
||||
case Toolbar.BUTTON_NONE:
|
||||
break;
|
||||
default:
|
||||
Timber.e("Button " + type + "pressed - how can this be?");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -366,34 +362,31 @@ public class LoginActivity extends BaseActivity
|
||||
public void onWalletDetails(final String walletName) {
|
||||
Timber.d("details for wallet .%s.", walletName);
|
||||
if (checkServiceRunning()) return;
|
||||
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
switch (which) {
|
||||
case DialogInterface.BUTTON_POSITIVE:
|
||||
final File walletFile = Helper.getWalletFile(LoginActivity.this, walletName);
|
||||
if (WalletManager.getInstance().walletExists(walletFile)) {
|
||||
Helper.promptPassword(LoginActivity.this, walletName, true, new Helper.PasswordAction() {
|
||||
@Override
|
||||
public void act(String walletName, String password, boolean fingerprintUsed) {
|
||||
if (checkDevice(walletName, password))
|
||||
startDetails(walletFile, password, GenerateReviewFragment.VIEW_TYPE_DETAILS);
|
||||
}
|
||||
DialogInterface.OnClickListener dialogClickListener = (dialog, which) -> {
|
||||
switch (which) {
|
||||
case DialogInterface.BUTTON_POSITIVE:
|
||||
final File walletFile = Helper.getWalletFile(LoginActivity.this, walletName);
|
||||
if (WalletManager.getInstance().walletExists(walletFile)) {
|
||||
Helper.promptPassword(LoginActivity.this, walletName, true, new Helper.PasswordAction() {
|
||||
@Override
|
||||
public void act(String walletName1, String password, boolean fingerprintUsed) {
|
||||
if (checkDevice(walletName1, 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);
|
||||
Toast.makeText(LoginActivity.this, getString(R.string.bad_wallet), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
break;
|
||||
@Override
|
||||
public void fail(String walletName) {
|
||||
}
|
||||
});
|
||||
} else { // this cannot really happen as we prefilter choices
|
||||
Timber.e("Wallet missing: %s", walletName);
|
||||
Toast.makeText(LoginActivity.this, getString(R.string.bad_wallet), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
break;
|
||||
|
||||
case DialogInterface.BUTTON_NEGATIVE:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
case DialogInterface.BUTTON_NEGATIVE:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -418,7 +411,7 @@ public class LoginActivity extends BaseActivity
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fail(String walletName, String password, boolean fingerprintUsed) {
|
||||
public void fail(String walletName) {
|
||||
}
|
||||
});
|
||||
} else { // this cannot really happen as we prefilter choices
|
||||
@@ -713,11 +706,11 @@ public class LoginActivity extends BaseActivity
|
||||
break;
|
||||
case NetworkType_Testnet:
|
||||
toolbar.setSubtitle(getString(R.string.connect_testnet));
|
||||
toolbar.setBackgroundResource(ColorHelper.getThemedResourceId(this, R.attr.colorPrimaryDark));
|
||||
toolbar.setBackgroundResource(ThemeHelper.getThemedResourceId(this, R.attr.colorPrimaryDark));
|
||||
break;
|
||||
case NetworkType_Stagenet:
|
||||
toolbar.setSubtitle(getString(R.string.connect_stagenet));
|
||||
toolbar.setBackgroundResource(ColorHelper.getThemedResourceId(this, R.attr.colorPrimaryDark));
|
||||
toolbar.setBackgroundResource(ThemeHelper.getThemedResourceId(this, R.attr.colorPrimaryDark));
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("NetworkType unknown: " + net);
|
||||
@@ -1406,7 +1399,7 @@ public class LoginActivity extends BaseActivity
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fail(String walletName, String password, boolean fingerprintUsed) {
|
||||
public void fail(String walletName) {
|
||||
}
|
||||
|
||||
});
|
||||
|
@@ -258,7 +258,6 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||
walletList.addAll(walletInfos);
|
||||
filterList();
|
||||
adapter.setInfos(displayedList);
|
||||
adapter.notifyDataSetChanged();
|
||||
|
||||
// deal with Gunther & FAB animation
|
||||
if (displayedList.isEmpty()) {
|
||||
|
@@ -524,7 +524,7 @@ public class NodeFragment extends Fragment
|
||||
.setNegativeButton(getString(R.string.label_cancel),
|
||||
(dialog, id) -> {
|
||||
closeDialog();
|
||||
nodesAdapter.dataSetChanged(); // to refresh test results
|
||||
nodesAdapter.setNodes(); // to refresh test results
|
||||
});
|
||||
|
||||
editDialog = alertDialogBuilder.create();
|
||||
@@ -588,7 +588,7 @@ public class NodeFragment extends Fragment
|
||||
if (nodeBackup == null) {
|
||||
nodesAdapter.addNode(nodeInfo);
|
||||
} else {
|
||||
nodesAdapter.dataSetChanged();
|
||||
nodesAdapter.setNodes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -73,14 +73,7 @@ public class ScannerFragment extends Fragment implements ZXingScannerView.Result
|
||||
// * On older devices continuously stopping and resuming camera preview can result in freezing the app.
|
||||
// * I don't know why this is the case but I don't have the time to figure out.
|
||||
Handler handler = new Handler();
|
||||
handler.postDelayed(new
|
||||
|
||||
Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mScannerView.resumeCameraPreview(ScannerFragment.this);
|
||||
}
|
||||
}, 2000);
|
||||
handler.postDelayed(() -> mScannerView.resumeCameraPreview(ScannerFragment.this), 2000);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -16,8 +16,11 @@
|
||||
|
||||
package com.m2049r.xmrwallet;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Paint;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.text.InputType;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -25,6 +28,7 @@ import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
@@ -32,10 +36,12 @@ import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.google.android.material.transition.MaterialContainerTransform;
|
||||
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.ThemeHelper;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
import com.m2049r.xmrwallet.widget.Toolbar;
|
||||
|
||||
@@ -77,6 +83,9 @@ public class TxFragment extends Fragment {
|
||||
private TextView tvTxXmrToKey;
|
||||
private TextView tvDestinationBtc;
|
||||
private TextView tvTxAmountBtc;
|
||||
private TextView tvXmrToSupport;
|
||||
private TextView tvXmrToKeyLabel;
|
||||
private ImageView tvXmrToLogo;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
@@ -88,6 +97,9 @@ public class TxFragment extends Fragment {
|
||||
tvTxXmrToKey = view.findViewById(R.id.tvTxXmrToKey);
|
||||
tvDestinationBtc = view.findViewById(R.id.tvDestinationBtc);
|
||||
tvTxAmountBtc = view.findViewById(R.id.tvTxAmountBtc);
|
||||
tvXmrToSupport = view.findViewById(R.id.tvXmrToSupport);
|
||||
tvXmrToKeyLabel = view.findViewById(R.id.tvXmrToKeyLabel);
|
||||
tvXmrToLogo = view.findViewById(R.id.tvXmrToLogo);
|
||||
|
||||
tvAccount = view.findViewById(R.id.tvAccount);
|
||||
tvAddress = view.findViewById(R.id.tvAddress);
|
||||
@@ -104,12 +116,9 @@ public class TxFragment extends Fragment {
|
||||
|
||||
etTxNotes.setRawInputType(InputType.TYPE_CLASS_TEXT);
|
||||
|
||||
tvTxXmrToKey.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
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();
|
||||
}
|
||||
tvTxXmrToKey.setOnClickListener(v -> {
|
||||
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();
|
||||
});
|
||||
|
||||
Bundle args = getArguments();
|
||||
@@ -283,12 +292,36 @@ public class TxFragment extends Fragment {
|
||||
showBtcInfo();
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
void showBtcInfo() {
|
||||
if (userNotes.xmrtoKey != null) {
|
||||
cvXmrTo.setVisibility(View.VISIBLE);
|
||||
tvTxXmrToKey.setText(userNotes.xmrtoKey);
|
||||
String key = userNotes.xmrtoKey;
|
||||
if ("xmrto".equals(userNotes.xmrtoTag)) { // legacy xmr.to service :(
|
||||
key = "xmrto-" + key;
|
||||
}
|
||||
tvTxXmrToKey.setText(key);
|
||||
tvDestinationBtc.setText(userNotes.xmrtoDestination);
|
||||
tvTxAmountBtc.setText(userNotes.xmrtoAmount + " BTC");
|
||||
tvTxAmountBtc.setText(userNotes.xmrtoAmount + " " + userNotes.xmrtoCurrency);
|
||||
switch (userNotes.xmrtoTag) {
|
||||
case "xmrto":
|
||||
tvXmrToSupport.setVisibility(View.GONE);
|
||||
tvXmrToKeyLabel.setVisibility(View.INVISIBLE);
|
||||
tvXmrToLogo.setImageResource(R.drawable.ic_xmrto_logo);
|
||||
break;
|
||||
case "side": // defaults in layout - just add underline
|
||||
tvXmrToSupport.setPaintFlags(tvXmrToSupport.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
|
||||
tvXmrToSupport.setOnClickListener(v -> {
|
||||
Uri uri = Uri.parse("https://sideshift.ai/orders/" + userNotes.xmrtoKey);
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
|
||||
startActivity(intent);
|
||||
});
|
||||
break;
|
||||
default:
|
||||
tvXmrToSupport.setVisibility(View.GONE);
|
||||
tvXmrToKeyLabel.setVisibility(View.INVISIBLE);
|
||||
tvXmrToLogo.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
cvXmrTo.setVisibility(View.GONE);
|
||||
}
|
||||
@@ -298,6 +331,11 @@ public class TxFragment extends Fragment {
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
final MaterialContainerTransform transform = new MaterialContainerTransform();
|
||||
transform.setDrawingViewId(R.id.fragment_container);
|
||||
transform.setDuration(getResources().getInteger(R.integer.tx_item_transition_duration));
|
||||
transform.setAllContainerColors(ThemeHelper.getThemedColor(getContext(), R.attr.colorSurface));
|
||||
setSharedElementEnterTransition(transform);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -36,12 +36,14 @@ import android.widget.ProgressBar;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
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.google.android.material.transition.MaterialElevationScale;
|
||||
import com.m2049r.xmrwallet.layout.TransactionInfoAdapter;
|
||||
import com.m2049r.xmrwallet.model.TransactionInfo;
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
@@ -49,19 +51,21 @@ import com.m2049r.xmrwallet.service.exchange.api.ExchangeApi;
|
||||
import com.m2049r.xmrwallet.service.exchange.api.ExchangeCallback;
|
||||
import com.m2049r.xmrwallet.service.exchange.api.ExchangeRate;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
import com.m2049r.xmrwallet.util.ServiceHelper;
|
||||
import com.m2049r.xmrwallet.widget.Toolbar;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
public class WalletFragment extends Fragment
|
||||
implements TransactionInfoAdapter.OnInteractionListener {
|
||||
private TransactionInfoAdapter adapter;
|
||||
private NumberFormat formatter = NumberFormat.getInstance();
|
||||
private final NumberFormat formatter = NumberFormat.getInstance();
|
||||
|
||||
private TextView tvStreetView;
|
||||
private LinearLayout llBalance;
|
||||
@@ -78,7 +82,7 @@ public class WalletFragment extends Fragment
|
||||
|
||||
private Spinner sCurrency;
|
||||
|
||||
private List<String> dismissedTransactions = new ArrayList<>();
|
||||
private final List<String> dismissedTransactions = new ArrayList<>();
|
||||
|
||||
public void resetDismissedTransactions() {
|
||||
dismissedTransactions.clear();
|
||||
@@ -91,7 +95,7 @@ public class WalletFragment extends Fragment
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
|
||||
if (activityCallback.hasWallet())
|
||||
inflater.inflate(R.menu.wallet_menu, menu);
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
@@ -102,6 +106,13 @@ public class WalletFragment extends Fragment
|
||||
Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_wallet, 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);
|
||||
|
||||
ivStreetGunther = view.findViewById(R.id.ivStreetGunther);
|
||||
tvStreetView = view.findViewById(R.id.tvStreetView);
|
||||
llBalance = view.findViewById(R.id.llBalance);
|
||||
@@ -122,7 +133,7 @@ public class WalletFragment extends Fragment
|
||||
List<String> currencies = new ArrayList<>();
|
||||
currencies.add(Helper.BASE_CRYPTO);
|
||||
currencies.addAll(Arrays.asList(getResources().getStringArray(R.array.currency)));
|
||||
ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<>(getContext(), R.layout.item_spinner_balance, currencies);
|
||||
ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<>(Objects.requireNonNull(getContext()), R.layout.item_spinner_balance, currencies);
|
||||
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
sCurrency.setAdapter(spinnerAdapter);
|
||||
|
||||
@@ -153,7 +164,6 @@ public class WalletFragment extends Fragment
|
||||
dismissedTransactions.add(adapter.getItem(position).hash);
|
||||
adapter.removeItem(position);
|
||||
}
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -162,25 +172,14 @@ public class WalletFragment extends Fragment
|
||||
dismissedTransactions.add(adapter.getItem(position).hash);
|
||||
adapter.removeItem(position);
|
||||
}
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
|
||||
recyclerView.addOnItemTouchListener(swipeTouchListener);
|
||||
|
||||
|
||||
bSend.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
activityCallback.onSendRequest();
|
||||
}
|
||||
});
|
||||
bReceive.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
activityCallback.onWalletReceive();
|
||||
}
|
||||
});
|
||||
bSend.setOnClickListener(v -> activityCallback.onSendRequest(v));
|
||||
bReceive.setOnClickListener(v -> activityCallback.onWalletReceive(v));
|
||||
|
||||
sCurrency.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
@@ -203,6 +202,16 @@ public class WalletFragment extends Fragment
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
postponeEnterTransition();
|
||||
view.getViewTreeObserver().addOnPreDrawListener(() -> {
|
||||
startPostponedEnterTransition();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
void showBalance(String balance) {
|
||||
tvBalance.setText(balance);
|
||||
final boolean streetMode = activityCallback.isStreetMode();
|
||||
@@ -242,7 +251,7 @@ public class WalletFragment extends Fragment
|
||||
String balanceCurrency = Helper.BASE_CRYPTO;
|
||||
double balanceRate = 1.0;
|
||||
|
||||
private final ExchangeApi exchangeApi = Helper.getExchangeApi();
|
||||
private final ExchangeApi exchangeApi = ServiceHelper.getExchangeApi();
|
||||
|
||||
void refreshBalance() {
|
||||
double unconfirmedXmr = Helper.getDecimalAmount(balance - unlockedBalance).doubleValue();
|
||||
@@ -260,24 +269,14 @@ public class WalletFragment extends Fragment
|
||||
@Override
|
||||
public void onSuccess(final ExchangeRate exchangeRate) {
|
||||
if (isAdded())
|
||||
new Handler(Looper.getMainLooper()).post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
exchange(exchangeRate);
|
||||
}
|
||||
});
|
||||
new Handler(Looper.getMainLooper()).post(() -> exchange(exchangeRate));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(final Exception e) {
|
||||
Timber.e(e.getLocalizedMessage());
|
||||
if (isAdded())
|
||||
new Handler(Looper.getMainLooper()).post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
exchangeFailed();
|
||||
}
|
||||
});
|
||||
new Handler(Looper.getMainLooper()).post(() -> exchangeFailed());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@@ -333,7 +332,13 @@ public class WalletFragment extends Fragment
|
||||
// Callbacks from TransactionInfoAdapter
|
||||
@Override
|
||||
public void onInteraction(final View view, final TransactionInfo infoItem) {
|
||||
activityCallback.onTxDetailsRequest(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);
|
||||
}
|
||||
|
||||
// called from activity
|
||||
@@ -351,7 +356,6 @@ public class WalletFragment extends Fragment
|
||||
list.add(info);
|
||||
}
|
||||
adapter.setInfos(list);
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
updateStatus(wallet);
|
||||
}
|
||||
@@ -413,7 +417,6 @@ public class WalletFragment extends Fragment
|
||||
void setActivityTitle(Wallet wallet) {
|
||||
if (wallet == null) return;
|
||||
walletTitle = wallet.getName();
|
||||
String watchOnly = (wallet.isWatchOnly() ? getString(R.string.label_watchonly) : "");
|
||||
walletSubtitle = wallet.getAccountLabel();
|
||||
activityCallback.setTitle(walletTitle, walletSubtitle);
|
||||
Timber.d("wallet title is %s", walletTitle);
|
||||
@@ -437,7 +440,7 @@ public class WalletFragment extends Fragment
|
||||
balance = wallet.getBalance();
|
||||
unlockedBalance = wallet.getUnlockedBalance();
|
||||
refreshBalance();
|
||||
String sync = "";
|
||||
String sync;
|
||||
if (!activityCallback.hasBoundService())
|
||||
throw new IllegalStateException("WalletService not bound.");
|
||||
Wallet.ConnectionStatus daemonConnected = activityCallback.getConnectionStatus();
|
||||
@@ -478,9 +481,9 @@ public class WalletFragment extends Fragment
|
||||
|
||||
long getDaemonHeight(); //mBoundService.getDaemonHeight();
|
||||
|
||||
void onSendRequest();
|
||||
void onSendRequest(View view);
|
||||
|
||||
void onTxDetailsRequest(TransactionInfo info);
|
||||
void onTxDetailsRequest(View view, TransactionInfo info);
|
||||
|
||||
boolean isSynced();
|
||||
|
||||
@@ -492,7 +495,7 @@ public class WalletFragment extends Fragment
|
||||
|
||||
String getTxKey(String txId);
|
||||
|
||||
void onWalletReceive();
|
||||
void onWalletReceive(View view);
|
||||
|
||||
boolean hasWallet();
|
||||
|
||||
@@ -506,7 +509,7 @@ public class WalletFragment 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;
|
||||
@@ -549,7 +552,7 @@ public class WalletFragment extends Fragment
|
||||
//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);
|
||||
streetGunther = ContextCompat.getDrawable(Objects.requireNonNull(getContext()), R.drawable.ic_gunther_streetmode);
|
||||
ivStreetGunther.setImageDrawable(streetGunther);
|
||||
} else
|
||||
ivStreetGunther.setImageDrawable(null);
|
||||
|
@@ -16,14 +16,13 @@
|
||||
|
||||
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.BuildConfig;
|
||||
import com.m2049r.xmrwallet.model.NetworkType;
|
||||
import com.m2049r.xmrwallet.util.DayNightMode;
|
||||
import com.m2049r.xmrwallet.util.LocaleHelper;
|
||||
import com.m2049r.xmrwallet.util.NightmodeHelper;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
89
app/src/main/java/com/m2049r/xmrwallet/data/Crypto.java
Normal file
89
app/src/main/java/com/m2049r/xmrwallet/data/Crypto.java
Normal file
@@ -0,0 +1,89 @@
|
||||
package com.m2049r.xmrwallet.data;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.m2049r.xmrwallet.R;
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
import com.m2049r.xmrwallet.util.validator.BitcoinAddressType;
|
||||
import com.m2049r.xmrwallet.util.validator.BitcoinAddressValidator;
|
||||
import com.m2049r.xmrwallet.util.validator.EthAddressValidator;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public enum Crypto {
|
||||
XMR("XMR", true, "monero:tx_amount:recipient_name:tx_description", R.id.ibXMR, R.drawable.ic_monero, R.drawable.ic_monero_bw, Wallet::isAddressValid),
|
||||
BTC("BTC", true, "bitcoin:amount:label:message", R.id.ibBTC, R.drawable.ic_xmrto_btc, R.drawable.ic_xmrto_btc_off, address -> {
|
||||
return BitcoinAddressValidator.validate(address, BitcoinAddressType.BTC);
|
||||
}),
|
||||
DASH("DASH", true, "dash:amount:label:message", R.id.ibDASH, R.drawable.ic_xmrto_dash, R.drawable.ic_xmrto_dash_off, address -> {
|
||||
return BitcoinAddressValidator.validate(address, BitcoinAddressType.DASH);
|
||||
}),
|
||||
DOGE("DOGE", true, "dogecoin:amount:label:message", R.id.ibDOGE, R.drawable.ic_xmrto_doge, R.drawable.ic_xmrto_doge_off, address -> {
|
||||
return BitcoinAddressValidator.validate(address, BitcoinAddressType.DOGE);
|
||||
}),
|
||||
ETH("ETH", false, "ethereum:amount:label:message", R.id.ibETH, R.drawable.ic_xmrto_eth, R.drawable.ic_xmrto_eth_off, EthAddressValidator::validate),
|
||||
LTC("LTC", true, "litecoin:amount:label:message", R.id.ibLTC, R.drawable.ic_xmrto_ltc, R.drawable.ic_xmrto_ltc_off, address -> {
|
||||
return BitcoinAddressValidator.validate(address, BitcoinAddressType.LTC);
|
||||
});
|
||||
|
||||
@Getter
|
||||
@NonNull
|
||||
private final String symbol;
|
||||
@Getter
|
||||
private final boolean casefull;
|
||||
@NonNull
|
||||
private final String uriSpec;
|
||||
@Getter
|
||||
private final int buttonId;
|
||||
@Getter
|
||||
private final int iconEnabledId;
|
||||
@Getter
|
||||
private final int iconDisabledId;
|
||||
@NonNull
|
||||
private final Validator validator;
|
||||
|
||||
@Nullable
|
||||
public static Crypto withScheme(@NonNull String scheme) {
|
||||
for (Crypto crypto : values()) {
|
||||
if (crypto.getUriScheme().equals(scheme)) return crypto;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Crypto withSymbol(@NonNull String symbol) {
|
||||
final String upperSymbol = symbol.toUpperCase();
|
||||
for (Crypto crypto : values()) {
|
||||
if (crypto.symbol.equals(upperSymbol)) return crypto;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
interface Validator {
|
||||
boolean validate(String address);
|
||||
}
|
||||
|
||||
// TODO maybe cache these segments
|
||||
String getUriScheme() {
|
||||
return uriSpec.split(":")[0];
|
||||
}
|
||||
|
||||
String getUriAmount() {
|
||||
return uriSpec.split(":")[1];
|
||||
}
|
||||
|
||||
String getUriLabel() {
|
||||
return uriSpec.split(":")[2];
|
||||
}
|
||||
|
||||
String getUriMessage() {
|
||||
return uriSpec.split(":")[3];
|
||||
}
|
||||
|
||||
boolean validate(String address) {
|
||||
return validator.validate(address);
|
||||
}
|
||||
}
|
@@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2020 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.data;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
|
@@ -64,12 +64,14 @@ public class Node {
|
||||
return hostAddress.hashCode();
|
||||
}
|
||||
|
||||
// Nodes are equal if they are the same host address & are on the same network
|
||||
// Nodes are equal if they are the same host address:port & are on the same network
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof Node)) return false;
|
||||
final Node anotherNode = (Node) other;
|
||||
return (hostAddress.equals(anotherNode.hostAddress) && (networkType == anotherNode.networkType));
|
||||
return (hostAddress.equals(anotherNode.hostAddress)
|
||||
&& (rpcPort == anotherNode.rpcPort)
|
||||
&& (networkType == anotherNode.networkType));
|
||||
}
|
||||
|
||||
static public Node fromString(String nodeString) {
|
||||
|
@@ -227,8 +227,7 @@ public class NodeInfo extends Node {
|
||||
if (response.isSuccessful()) {
|
||||
ResponseBody respBody = response.body(); // closed through Response object
|
||||
if ((respBody != null) && (respBody.contentLength() < 2000)) { // sanity check
|
||||
final JSONObject json = new JSONObject(
|
||||
respBody.string());
|
||||
final JSONObject json = new JSONObject(respBody.string());
|
||||
String rpcVersion = json.getString("jsonrpc");
|
||||
if (!RPC_VERSION.equals(rpcVersion))
|
||||
return false;
|
||||
|
@@ -20,6 +20,7 @@ import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import com.m2049r.xmrwallet.model.PendingTransaction;
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
|
||||
// https://stackoverflow.com/questions/2139134/how-to-send-an-object-from-one-android-activity-to-another-using-intents
|
||||
public class TxData implements Parcelable {
|
||||
@@ -52,6 +53,10 @@ public class TxData implements Parcelable {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public double getAmountAsDouble() {
|
||||
return 1.0 * amount / 1000000000000L;
|
||||
}
|
||||
|
||||
public int getMixin() {
|
||||
return mixin;
|
||||
}
|
||||
@@ -68,6 +73,10 @@ public class TxData implements Parcelable {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public void setAmount(double amount) {
|
||||
this.amount = Wallet.getAmountFromDouble(amount);
|
||||
}
|
||||
|
||||
public void setMixin(int mixin) {
|
||||
this.mixin = mixin;
|
||||
}
|
||||
|
@@ -18,11 +18,23 @@ package com.m2049r.xmrwallet.data;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
public class TxDataBtc extends TxData {
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
private String xmrtoUuid;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
public class TxDataBtc extends TxData {
|
||||
@Getter
|
||||
@Setter
|
||||
private String btcSymbol; // the actual non-XMR thing we're sending
|
||||
@Getter
|
||||
@Setter
|
||||
private String xmrtoOrderId; // shown in success screen
|
||||
@Getter
|
||||
@Setter
|
||||
private String btcAddress;
|
||||
private String bip70;
|
||||
@Getter
|
||||
@Setter
|
||||
private double btcAmount;
|
||||
|
||||
public TxDataBtc() {
|
||||
@@ -33,44 +45,12 @@ public class TxDataBtc extends TxData {
|
||||
super(txDataBtc);
|
||||
}
|
||||
|
||||
public String getXmrtoUuid() {
|
||||
return xmrtoUuid;
|
||||
}
|
||||
|
||||
public void setXmrtoUuid(String xmrtoUuid) {
|
||||
this.xmrtoUuid = xmrtoUuid;
|
||||
}
|
||||
|
||||
public String getBtcAddress() {
|
||||
return btcAddress;
|
||||
}
|
||||
|
||||
public void setBtcAddress(String btcAddress) {
|
||||
this.btcAddress = btcAddress;
|
||||
}
|
||||
|
||||
public String getBip70() {
|
||||
return bip70;
|
||||
}
|
||||
|
||||
public void setBip70(String bip70) {
|
||||
this.bip70 = bip70;
|
||||
}
|
||||
|
||||
public double getBtcAmount() {
|
||||
return btcAmount;
|
||||
}
|
||||
|
||||
public void setBtcAmount(double btcAmount) {
|
||||
this.btcAmount = btcAmount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
super.writeToParcel(out, flags);
|
||||
out.writeString(xmrtoUuid);
|
||||
out.writeString(btcSymbol);
|
||||
out.writeString(xmrtoOrderId);
|
||||
out.writeString(btcAddress);
|
||||
out.writeString(bip70);
|
||||
out.writeDouble(btcAmount);
|
||||
}
|
||||
|
||||
@@ -87,23 +67,35 @@ public class TxDataBtc extends TxData {
|
||||
|
||||
protected TxDataBtc(Parcel in) {
|
||||
super(in);
|
||||
xmrtoUuid = in.readString();
|
||||
btcSymbol = in.readString();
|
||||
xmrtoOrderId = in.readString();
|
||||
btcAddress = in.readString();
|
||||
bip70 = in.readString();
|
||||
btcAmount = in.readDouble();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(",xmrtoUuid:");
|
||||
sb.append(xmrtoUuid);
|
||||
sb.append("xmrtoOrderId:");
|
||||
sb.append(xmrtoOrderId);
|
||||
sb.append(",btcSymbol:");
|
||||
sb.append(btcSymbol);
|
||||
sb.append(",btcAddress:");
|
||||
sb.append(btcAddress);
|
||||
sb.append(",bip70:");
|
||||
sb.append(bip70);
|
||||
sb.append(",btcAmount:");
|
||||
sb.append(btcAmount);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public boolean validateAddress(@NonNull String address) {
|
||||
if ((btcSymbol == null) || (btcAddress == null)) return false;
|
||||
final Crypto crypto = Crypto.withSymbol(btcSymbol);
|
||||
if (crypto == null) return false;
|
||||
if (crypto.isCasefull()) { // compare as-is
|
||||
return address.equals(btcAddress);
|
||||
} else { // normalize & compare (e.g. ETH with and without checksum capitals
|
||||
return address.toLowerCase().equals(btcAddress.toLowerCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -16,18 +16,19 @@
|
||||
|
||||
package com.m2049r.xmrwallet.data;
|
||||
|
||||
import com.m2049r.xmrwallet.xmrto.api.QueryOrderStatus;
|
||||
import com.m2049r.xmrwallet.service.shift.sideshift.api.CreateOrder;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
public class UserNotes {
|
||||
public String txNotes = "";
|
||||
public String note = "";
|
||||
public String xmrtoTag = null;
|
||||
public String xmrtoKey = null;
|
||||
public String xmrtoAmount = null; // could be a double - but we are not doing any calculations
|
||||
public String xmrtoCurrency = null;
|
||||
public String xmrtoDestination = null;
|
||||
|
||||
public UserNotes(final String txNotes) {
|
||||
@@ -35,13 +36,15 @@ public class UserNotes {
|
||||
return;
|
||||
}
|
||||
this.txNotes = txNotes;
|
||||
Pattern p = Pattern.compile("^\\{(xmrto-\\w{6}),([0-9.]*)BTC,(\\w*)\\} ?(.*)");
|
||||
Pattern p = Pattern.compile("^\\{([a-z]+)-(\\w{6,}),([0-9.]*)([A-Z]+),(\\w*)\\} ?(.*)");
|
||||
Matcher m = p.matcher(txNotes);
|
||||
if (m.find()) {
|
||||
xmrtoKey = m.group(1);
|
||||
xmrtoAmount = m.group(2);
|
||||
xmrtoDestination = m.group(3);
|
||||
note = m.group(4);
|
||||
xmrtoTag = m.group(1);
|
||||
xmrtoKey = m.group(2);
|
||||
xmrtoAmount = m.group(3);
|
||||
xmrtoCurrency = m.group(4);
|
||||
xmrtoDestination = m.group(5);
|
||||
note = m.group(6);
|
||||
} else {
|
||||
note = txNotes;
|
||||
}
|
||||
@@ -56,12 +59,15 @@ public class UserNotes {
|
||||
txNotes = buildTxNote();
|
||||
}
|
||||
|
||||
public void setXmrtoStatus(QueryOrderStatus xmrtoStatus) {
|
||||
if (xmrtoStatus != null) {
|
||||
xmrtoKey = xmrtoStatus.getUuid();
|
||||
xmrtoAmount = String.valueOf(xmrtoStatus.getBtcAmount());
|
||||
xmrtoDestination = xmrtoStatus.getBtcDestAddress();
|
||||
public void setXmrtoOrder(CreateOrder order) {
|
||||
if (order != null) {
|
||||
xmrtoTag = order.TAG;
|
||||
xmrtoKey = order.getOrderId();
|
||||
xmrtoAmount = Helper.getDisplayAmount(order.getBtcAmount());
|
||||
xmrtoCurrency = order.getBtcCurrency();
|
||||
xmrtoDestination = order.getBtcAddress();
|
||||
} else {
|
||||
xmrtoTag = null;
|
||||
xmrtoKey = null;
|
||||
xmrtoAmount = null;
|
||||
xmrtoDestination = null;
|
||||
@@ -70,15 +76,18 @@ public class UserNotes {
|
||||
}
|
||||
|
||||
private String buildTxNote() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (xmrtoKey != null) {
|
||||
if ((xmrtoAmount == null) || (xmrtoDestination == null))
|
||||
throw new IllegalArgumentException("Broken notes");
|
||||
sb.append("{");
|
||||
sb.append(xmrtoTag);
|
||||
sb.append("-");
|
||||
sb.append(xmrtoKey);
|
||||
sb.append(",");
|
||||
sb.append(xmrtoAmount);
|
||||
sb.append("BTC,");
|
||||
sb.append(xmrtoCurrency);
|
||||
sb.append(",");
|
||||
sb.append(xmrtoDestination);
|
||||
sb.append("}");
|
||||
if ((note != null) && (!note.isEmpty()))
|
||||
|
@@ -27,7 +27,6 @@ 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;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -42,9 +42,8 @@ public class SendAmountWizardFragment extends SendWizardFragment {
|
||||
|
||||
Listener sendListener;
|
||||
|
||||
public SendAmountWizardFragment setSendListener(Listener listener) {
|
||||
public void setSendListener(Listener listener) {
|
||||
this.sendListener = listener;
|
||||
return this;
|
||||
}
|
||||
|
||||
interface Listener {
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -16,6 +16,9 @@
|
||||
|
||||
package com.m2049r.xmrwallet.fragment.send;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.Paint;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -27,15 +30,17 @@ import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.m2049r.xmrwallet.R;
|
||||
import com.m2049r.xmrwallet.data.Crypto;
|
||||
import com.m2049r.xmrwallet.data.PendingTx;
|
||||
import com.m2049r.xmrwallet.data.TxDataBtc;
|
||||
import com.m2049r.xmrwallet.service.shift.ShiftCallback;
|
||||
import com.m2049r.xmrwallet.service.shift.ShiftException;
|
||||
import com.m2049r.xmrwallet.service.shift.sideshift.api.QueryOrderStatus;
|
||||
import com.m2049r.xmrwallet.service.shift.sideshift.api.SideShiftApi;
|
||||
import com.m2049r.xmrwallet.service.shift.sideshift.network.SideShiftApiImpl;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
import com.m2049r.xmrwallet.util.OkHttpHelper;
|
||||
import com.m2049r.xmrwallet.xmrto.XmrToException;
|
||||
import com.m2049r.xmrwallet.xmrto.api.QueryOrderStatus;
|
||||
import com.m2049r.xmrwallet.xmrto.api.XmrToApi;
|
||||
import com.m2049r.xmrwallet.xmrto.api.XmrToCallback;
|
||||
import com.m2049r.xmrwallet.xmrto.network.XmrToApiImpl;
|
||||
import com.m2049r.xmrwallet.util.ServiceHelper;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Locale;
|
||||
@@ -52,23 +57,23 @@ public class SendBtcSuccessWizardFragment extends SendWizardFragment {
|
||||
|
||||
SendSuccessWizardFragment.Listener sendListener;
|
||||
|
||||
public SendBtcSuccessWizardFragment setSendListener(SendSuccessWizardFragment.Listener listener) {
|
||||
public void setSendListener(SendSuccessWizardFragment.Listener listener) {
|
||||
this.sendListener = listener;
|
||||
return this;
|
||||
}
|
||||
|
||||
ImageButton bCopyTxId;
|
||||
private TextView tvTxId;
|
||||
private TextView tvTxAddress;
|
||||
private TextView tvTxPaymentId;
|
||||
private TextView tvTxAmount;
|
||||
private TextView tvTxFee;
|
||||
private TextView tvXmrToAmount;
|
||||
private ImageView ivXmrToIcon;
|
||||
private TextView tvXmrToStatus;
|
||||
private ImageView ivXmrToStatus;
|
||||
private ImageView ivXmrToStatusBig;
|
||||
private ProgressBar pbXmrto;
|
||||
private TextView tvTxXmrToKey;
|
||||
private TextView tvXmrToSupport;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
@@ -87,13 +92,13 @@ public class SendBtcSuccessWizardFragment extends SendWizardFragment {
|
||||
});
|
||||
|
||||
tvXmrToAmount = view.findViewById(R.id.tvXmrToAmount);
|
||||
ivXmrToIcon = view.findViewById(R.id.ivXmrToIcon);
|
||||
tvXmrToStatus = view.findViewById(R.id.tvXmrToStatus);
|
||||
ivXmrToStatus = view.findViewById(R.id.ivXmrToStatus);
|
||||
ivXmrToStatusBig = view.findViewById(R.id.ivXmrToStatusBig);
|
||||
|
||||
tvTxId = view.findViewById(R.id.tvTxId);
|
||||
tvTxAddress = view.findViewById(R.id.tvTxAddress);
|
||||
tvTxPaymentId = view.findViewById(R.id.tvTxPaymentId);
|
||||
tvTxAmount = view.findViewById(R.id.tvTxAmount);
|
||||
tvTxFee = view.findViewById(R.id.tvTxFee);
|
||||
|
||||
@@ -101,14 +106,14 @@ public class SendBtcSuccessWizardFragment extends SendWizardFragment {
|
||||
pbXmrto.getIndeterminateDrawable().setColorFilter(0x61000000, android.graphics.PorterDuff.Mode.MULTIPLY);
|
||||
|
||||
tvTxXmrToKey = view.findViewById(R.id.tvTxXmrToKey);
|
||||
tvTxXmrToKey.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
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();
|
||||
}
|
||||
tvTxXmrToKey.setOnClickListener(v -> {
|
||||
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();
|
||||
});
|
||||
|
||||
tvXmrToSupport = view.findViewById(R.id.tvXmrToSupport);
|
||||
tvXmrToSupport.setPaintFlags(tvXmrToSupport.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@@ -147,9 +152,16 @@ public class SendBtcSuccessWizardFragment extends SendWizardFragment {
|
||||
NumberFormat df = NumberFormat.getInstance(Locale.US);
|
||||
df.setMaximumFractionDigits(12);
|
||||
String btcAmount = df.format(btcData.getBtcAmount());
|
||||
tvXmrToAmount.setText(getString(R.string.info_send_xmrto_success_btc, btcAmount));
|
||||
tvXmrToAmount.setText(getString(R.string.info_send_xmrto_success_btc, btcAmount, btcData.getBtcSymbol()));
|
||||
//TODO btcData.getBtcAddress();
|
||||
tvTxXmrToKey.setText(btcData.getXmrtoUuid());
|
||||
tvTxXmrToKey.setText(btcData.getXmrtoOrderId());
|
||||
final Crypto crypto = Crypto.withSymbol(btcData.getBtcSymbol());
|
||||
ivXmrToIcon.setImageResource(crypto.getIconEnabledId());
|
||||
tvXmrToSupport.setOnClickListener(v -> {
|
||||
Uri orderUri = getXmrToApi().getQueryOrderUri(btcData.getXmrtoOrderId());
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, orderUri);
|
||||
startActivity(intent);
|
||||
});
|
||||
queryOrder();
|
||||
} else {
|
||||
throw new IllegalStateException("btcData is null");
|
||||
@@ -158,33 +170,23 @@ public class SendBtcSuccessWizardFragment extends SendWizardFragment {
|
||||
sendListener.enableDone();
|
||||
}
|
||||
|
||||
private final int QUERY_INTERVAL = 1000; // ms
|
||||
|
||||
private void processQueryOrder(final QueryOrderStatus status) {
|
||||
Timber.d("processQueryOrder %s for %s", status.getState().toString(), status.getUuid());
|
||||
if (!btcData.getXmrtoUuid().equals(status.getUuid()))
|
||||
Timber.d("processQueryOrder %s for %s", status.getState().toString(), status.getOrderId());
|
||||
if (!btcData.getXmrtoOrderId().equals(status.getOrderId()))
|
||||
throw new IllegalStateException("UUIDs do not match!");
|
||||
if (isResumed && (getView() != null))
|
||||
getView().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
showXmrToStatus(status);
|
||||
if (!status.isTerminal()) {
|
||||
getView().postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
queryOrder();
|
||||
}
|
||||
}, QUERY_INTERVAL);
|
||||
}
|
||||
getView().post(() -> {
|
||||
showXmrToStatus(status);
|
||||
if (!status.isTerminal()) {
|
||||
getView().postDelayed(this::queryOrder, SideShiftApi.QUERY_INTERVAL);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void queryOrder() {
|
||||
Timber.d("queryOrder(%s)", btcData.getXmrtoUuid());
|
||||
Timber.d("queryOrder(%s)", btcData.getXmrtoOrderId());
|
||||
if (!isResumed) return;
|
||||
getXmrToApi().queryOrderStatus(btcData.getXmrtoUuid(), new XmrToCallback<QueryOrderStatus>() {
|
||||
getXmrToApi().queryOrderStatus(btcData.getXmrtoOrderId(), new ShiftCallback<QueryOrderStatus>() {
|
||||
@Override
|
||||
public void onSuccess(QueryOrderStatus status) {
|
||||
if (!isAdded()) return;
|
||||
@@ -194,38 +196,34 @@ public class SendBtcSuccessWizardFragment extends SendWizardFragment {
|
||||
@Override
|
||||
public void onError(final Exception ex) {
|
||||
if (!isResumed) return;
|
||||
Timber.e(ex);
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (ex instanceof XmrToException) {
|
||||
Toast.makeText(getActivity(), ((XmrToException) ex).getError().getErrorMsg(), Toast.LENGTH_LONG).show();
|
||||
} else {
|
||||
Toast.makeText(getActivity(), ex.getLocalizedMessage(), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
Timber.w(ex);
|
||||
getActivity().runOnUiThread(() -> {
|
||||
if (ex instanceof ShiftException) {
|
||||
Toast.makeText(getActivity(), ((ShiftException) ex).getError().getErrorMsg(), Toast.LENGTH_LONG).show();
|
||||
} else {
|
||||
Toast.makeText(getActivity(), ex.getLocalizedMessage(), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private int statusResource = 0;
|
||||
|
||||
void showXmrToStatus(final QueryOrderStatus status) {
|
||||
int statusResource = 0;
|
||||
if (status.isError()) {
|
||||
tvXmrToStatus.setText(getString(R.string.info_send_xmrto_error, status.toString()));
|
||||
statusResource = R.drawable.ic_error_red_24dp;
|
||||
pbXmrto.getIndeterminateDrawable().setColorFilter(0xff8b0000, android.graphics.PorterDuff.Mode.MULTIPLY);
|
||||
} else if (status.isSent()) {
|
||||
tvXmrToStatus.setText(getString(R.string.info_send_xmrto_sent));
|
||||
} else if (status.isSent() || status.isPaid()) {
|
||||
tvXmrToStatus.setText(getString(R.string.info_send_xmrto_sent, btcData.getBtcSymbol()));
|
||||
statusResource = R.drawable.ic_success_green_24dp;
|
||||
pbXmrto.getIndeterminateDrawable().setColorFilter(0xFF417505, android.graphics.PorterDuff.Mode.MULTIPLY);
|
||||
} else if (status.isWaiting()) {
|
||||
tvXmrToStatus.setText(getString(R.string.info_send_xmrto_unpaid));
|
||||
statusResource = R.drawable.ic_pending_orange_24dp;
|
||||
pbXmrto.getIndeterminateDrawable().setColorFilter(0xFFFF6105, android.graphics.PorterDuff.Mode.MULTIPLY);
|
||||
} else if (status.isPending()) {
|
||||
if (status.isPaid()) {
|
||||
tvXmrToStatus.setText(getString(R.string.info_send_xmrto_paid));
|
||||
} else {
|
||||
tvXmrToStatus.setText(getString(R.string.info_send_xmrto_unpaid));
|
||||
}
|
||||
tvXmrToStatus.setText(getString(R.string.info_send_xmrto_paid));
|
||||
statusResource = R.drawable.ic_pending_orange_24dp;
|
||||
pbXmrto.getIndeterminateDrawable().setColorFilter(0xFFFF6105, android.graphics.PorterDuff.Mode.MULTIPLY);
|
||||
} else {
|
||||
@@ -234,20 +232,21 @@ public class SendBtcSuccessWizardFragment extends SendWizardFragment {
|
||||
ivXmrToStatus.setImageResource(statusResource);
|
||||
if (status.isTerminal()) {
|
||||
pbXmrto.setVisibility(View.INVISIBLE);
|
||||
ivXmrToIcon.setVisibility(View.GONE);
|
||||
ivXmrToStatus.setVisibility(View.GONE);
|
||||
ivXmrToStatusBig.setImageResource(statusResource);
|
||||
ivXmrToStatusBig.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
private XmrToApi xmrToApi = null;
|
||||
private SideShiftApi xmrToApi = null;
|
||||
|
||||
private final XmrToApi getXmrToApi() {
|
||||
private SideShiftApi getXmrToApi() {
|
||||
if (xmrToApi == null) {
|
||||
synchronized (this) {
|
||||
if (xmrToApi == null) {
|
||||
xmrToApi = new XmrToApiImpl(OkHttpHelper.getOkHttpClient(),
|
||||
Helper.getXmrToBaseUrl());
|
||||
xmrToApi = new SideShiftApiImpl(OkHttpHelper.getOkHttpClient(),
|
||||
ServiceHelper.getXmrToBaseUrl());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -227,7 +227,7 @@ public class SendConfirmWizardFragment extends SendWizardFragment implements Sen
|
||||
send();
|
||||
}
|
||||
|
||||
public void fail(String walletName, String password, boolean fingerprintUsed) {
|
||||
public void fail(String walletName) {
|
||||
getActivity().runOnUiThread(() -> {
|
||||
bSend.setEnabled(true); // allow to try again
|
||||
});
|
||||
|
@@ -29,12 +29,14 @@ import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
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.google.android.material.transition.MaterialContainerTransform;
|
||||
import com.m2049r.xmrwallet.OnBackPressedListener;
|
||||
import com.m2049r.xmrwallet.OnUriScannedListener;
|
||||
import com.m2049r.xmrwallet.R;
|
||||
@@ -48,10 +50,12 @@ import com.m2049r.xmrwallet.layout.SpendViewPager;
|
||||
import com.m2049r.xmrwallet.model.PendingTransaction;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
import com.m2049r.xmrwallet.util.Notice;
|
||||
import com.m2049r.xmrwallet.util.ThemeHelper;
|
||||
import com.m2049r.xmrwallet.widget.DotBar;
|
||||
import com.m2049r.xmrwallet.widget.Toolbar;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Objects;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
@@ -92,8 +96,6 @@ public class SendFragment extends Fragment
|
||||
void setOnUriScannedListener(OnUriScannedListener onUriScannedListener);
|
||||
}
|
||||
|
||||
private EditText etDummy;
|
||||
|
||||
private View llNavBar;
|
||||
private DotBar dotBar;
|
||||
private Button bPrev;
|
||||
@@ -101,7 +103,7 @@ public class SendFragment extends Fragment
|
||||
|
||||
private Button bDone;
|
||||
|
||||
static private int MAX_FALLBACK = Integer.MAX_VALUE;
|
||||
static private final int MAX_FALLBACK = Integer.MAX_VALUE;
|
||||
|
||||
public static SendFragment newInstance(String uri) {
|
||||
SendFragment f = new SendFragment();
|
||||
@@ -166,28 +168,18 @@ public class SendFragment extends Fragment
|
||||
}
|
||||
});
|
||||
|
||||
bPrev.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
spendViewPager.previous();
|
||||
}
|
||||
});
|
||||
bPrev.setOnClickListener(v -> spendViewPager.previous());
|
||||
|
||||
bNext.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
spendViewPager.next();
|
||||
}
|
||||
});
|
||||
bNext.setOnClickListener(v -> spendViewPager.next());
|
||||
|
||||
bDone.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
Timber.d("bDone.onClick");
|
||||
activityCallback.onFragmentDone();
|
||||
}
|
||||
bDone.setOnClickListener(v -> {
|
||||
Timber.d("bDone.onClick");
|
||||
activityCallback.onFragmentDone();
|
||||
});
|
||||
|
||||
updatePosition(0);
|
||||
|
||||
etDummy = view.findViewById(R.id.etDummy);
|
||||
final EditText etDummy = view.findViewById(R.id.etDummy);
|
||||
etDummy.setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
|
||||
etDummy.requestFocus();
|
||||
Helper.hideKeyboard(getActivity());
|
||||
@@ -197,7 +189,7 @@ public class SendFragment extends Fragment
|
||||
String uri = args.getString(WalletActivity.REQUEST_URI);
|
||||
Timber.d("URI: %s", uri);
|
||||
if (uri != null) {
|
||||
barcodeData = BarcodeData.fromQrCode(uri);
|
||||
barcodeData = BarcodeData.fromString(uri);
|
||||
Timber.d("barcodeData: %s", barcodeData != null ? barcodeData.toString() : "null");
|
||||
}
|
||||
}
|
||||
@@ -236,7 +228,7 @@ public class SendFragment extends Fragment
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
public void onAttach(@NonNull Context context) {
|
||||
Timber.d("onAttach %s", context);
|
||||
super.onAttach(context);
|
||||
if (context instanceof Listener) {
|
||||
@@ -300,12 +292,7 @@ public class SendFragment extends Fragment
|
||||
default:
|
||||
throw new IllegalArgumentException("Mode " + String.valueOf(aMode) + " unknown!");
|
||||
}
|
||||
getView().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
pagerAdapter.notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
getView().post(() -> pagerAdapter.notifyDataSetChanged());
|
||||
Timber.d("New Mode = %s", mode.toString());
|
||||
}
|
||||
}
|
||||
@@ -325,7 +312,7 @@ public class SendFragment extends Fragment
|
||||
SparseArray<WeakReference<SendWizardFragment>> myFragments = new SparseArray<>();
|
||||
|
||||
public SpendPagerAdapter(FragmentManager fm) {
|
||||
super(fm);
|
||||
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
|
||||
}
|
||||
|
||||
public void addSuccess() {
|
||||
@@ -338,8 +325,9 @@ public class SendFragment extends Fragment
|
||||
return numPages;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Object instantiateItem(ViewGroup container, int position) {
|
||||
public Object instantiateItem(@NonNull ViewGroup container, int position) {
|
||||
Timber.d("instantiateItem %d", position);
|
||||
SendWizardFragment fragment = (SendWizardFragment) super.instantiateItem(container, position);
|
||||
myFragments.put(position, new WeakReference<>(fragment));
|
||||
@@ -347,20 +335,21 @@ public class SendFragment extends Fragment
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyItem(ViewGroup container, int position, Object object) {
|
||||
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
|
||||
Timber.d("destroyItem %d", position);
|
||||
myFragments.remove(position);
|
||||
super.destroyItem(container, position, object);
|
||||
}
|
||||
|
||||
public SendWizardFragment getFragment(int position) {
|
||||
WeakReference ref = myFragments.get(position);
|
||||
WeakReference<SendWizardFragment> ref = myFragments.get(position);
|
||||
if (ref != null)
|
||||
return myFragments.get(position).get();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public SendWizardFragment getItem(int position) {
|
||||
Timber.d("getItem(%d) CREATE", position);
|
||||
@@ -415,7 +404,7 @@ public class SendFragment extends Fragment
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemPosition(Object object) {
|
||||
public int getItemPosition(@NonNull Object object) {
|
||||
Timber.d("getItemPosition %s", String.valueOf(object));
|
||||
if (object instanceof SendAddressWizardFragment) {
|
||||
// keep these pages
|
||||
@@ -552,33 +541,19 @@ public class SendFragment extends Fragment
|
||||
enableNavigation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
final MaterialContainerTransform transform = new MaterialContainerTransform();
|
||||
transform.setDrawingViewId(R.id.fragment_container);
|
||||
transform.setDuration(getResources().getInteger(R.integer.tx_item_transition_duration));
|
||||
transform.setAllContainerColors(ThemeHelper.getThemedColor(Objects.requireNonNull(getContext()), R.attr.colorSurface));
|
||||
setSharedElementEnterTransition(transform);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
public void onCreateOptionsMenu(@NonNull Menu menu, MenuInflater inflater) {
|
||||
inflater.inflate(R.menu.send_menu, menu);
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
}
|
||||
|
||||
// xmr.to info box
|
||||
private static final String PREF_SHOW_XMRTO_ENABLED = "info_xmrto_enabled_send";
|
||||
|
||||
boolean showXmrtoEnabled = true;
|
||||
|
||||
void loadPrefs() {
|
||||
SharedPreferences sharedPref = activityCallback.getPrefs();
|
||||
showXmrtoEnabled = sharedPref.getBoolean(PREF_SHOW_XMRTO_ENABLED, true);
|
||||
}
|
||||
|
||||
void saveXmrToPrefs() {
|
||||
SharedPreferences sharedPref = activityCallback.getPrefs();
|
||||
SharedPreferences.Editor editor = sharedPref.edit();
|
||||
editor.putBoolean(PREF_SHOW_XMRTO_ENABLED, showXmrtoEnabled);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user