mirror of
https://github.com/m2049r/xmrwallet
synced 2025-09-08 20:40:51 +02:00
Compare commits
32 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
faf57c96fc | ||
![]() |
57ddddfce2 | ||
![]() |
ab6069058b | ||
![]() |
d94d6e6925 | ||
![]() |
4a819cc159 | ||
![]() |
f40c3d6c6d | ||
![]() |
82b25df7ad | ||
![]() |
08f815e830 | ||
![]() |
4e59be2dff | ||
![]() |
45c5883e11 | ||
![]() |
067a23e6a5 | ||
![]() |
d21fd41c44 | ||
![]() |
6632547d1e | ||
![]() |
f1b786ec3e | ||
![]() |
a93e96d34c | ||
![]() |
1829d30b61 | ||
![]() |
e5b15b7816 | ||
![]() |
7206857a5b | ||
![]() |
85d84d09ee | ||
![]() |
c6a1b503bc | ||
![]() |
8bda7aa0cf | ||
![]() |
97fb0a5483 | ||
![]() |
fc950c6772 | ||
![]() |
46add5e927 | ||
![]() |
fa0692ceab | ||
![]() |
ff4f4a1c2c | ||
![]() |
79abb89725 | ||
![]() |
ef8301fd6f | ||
![]() |
3a15c842ff | ||
![]() |
1697da55b5 | ||
![]() |
454f3e412a | ||
![]() |
d803a1e220 |
@@ -1,15 +1,15 @@
|
|||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 28
|
compileSdkVersion 29
|
||||||
buildToolsVersion '29.0.2'
|
buildToolsVersion '29.0.2'
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.m2049r.xmrwallet"
|
applicationId "com.m2049r.xmrwallet"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 28
|
targetSdkVersion 29
|
||||||
versionCode 403
|
versionCode 705
|
||||||
versionName "1.14.3 'On Board'"
|
versionName "1.17.5.1 'Druk'"
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
cppFlags "-std=c++11"
|
cppFlags "-std=c++11"
|
||||||
@@ -17,6 +17,11 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
bundle {
|
||||||
|
language {
|
||||||
|
enableSplit = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
flavorDimensions 'type', 'net'
|
flavorDimensions 'type', 'net'
|
||||||
productFlavors {
|
productFlavors {
|
||||||
@@ -28,6 +33,11 @@ android {
|
|||||||
applicationIdSuffix '.stage'
|
applicationIdSuffix '.stage'
|
||||||
versionNameSuffix ' (stage)'
|
versionNameSuffix ' (stage)'
|
||||||
}
|
}
|
||||||
|
devnet {
|
||||||
|
dimension 'net'
|
||||||
|
applicationIdSuffix '.test'
|
||||||
|
versionNameSuffix ' (test)'
|
||||||
|
}
|
||||||
alpha {
|
alpha {
|
||||||
dimension 'type'
|
dimension 'type'
|
||||||
applicationIdSuffix '.alpha'
|
applicationIdSuffix '.alpha'
|
||||||
@@ -46,6 +56,9 @@ android {
|
|||||||
debug {
|
debug {
|
||||||
applicationIdSuffix ".debug"
|
applicationIdSuffix ".debug"
|
||||||
}
|
}
|
||||||
|
applicationVariants.all { variant ->
|
||||||
|
variant.buildConfigField "String", "ID_A", "\"" + getId("ID_A") + "\""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
@@ -70,7 +83,8 @@ android {
|
|||||||
def availableLocales = ["en"]
|
def availableLocales = ["en"]
|
||||||
new File("app/src/main/res/").eachFileMatch(~/^values-.*/) { file ->
|
new File("app/src/main/res/").eachFileMatch(~/^values-.*/) { file ->
|
||||||
def languageTag = file.name.substring(7).replace("-r", "-")
|
def languageTag = file.name.substring(7).replace("-r", "-")
|
||||||
availableLocales.add(languageTag)
|
if (languageTag != "night")
|
||||||
|
availableLocales.add(languageTag)
|
||||||
}
|
}
|
||||||
|
|
||||||
// APKs for the same app that all have the same version information.
|
// APKs for the same app that all have the same version information.
|
||||||
@@ -81,8 +95,7 @@ android {
|
|||||||
variant.outputs.all {
|
variant.outputs.all {
|
||||||
output ->
|
output ->
|
||||||
def abiName = output.getFilter(com.android.build.OutputFile.ABI)
|
def abiName = output.getFilter(com.android.build.OutputFile.ABI)
|
||||||
output.versionCodeOverride = abiCodes.get(abiName, 0) + 10 * variant.versionCode
|
output.versionCodeOverride = abiCodes.get(abiName, 0) + 10 * versionCode
|
||||||
//def flavor = output.getFilter(flavor)
|
|
||||||
|
|
||||||
if (abiName == null) abiName = "universal"
|
if (abiName == null) abiName = "universal"
|
||||||
def v = "${variant.versionName}".replaceFirst(" '.*' ?", "")
|
def v = "${variant.versionName}".replaceFirst(" '.*' ?", "")
|
||||||
@@ -99,34 +112,42 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def getId(name) {
|
||||||
|
def Properties props = new Properties()
|
||||||
|
props.load(new FileInputStream(new File('monerujo.id')))
|
||||||
|
return props[name]
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation "com.android.support:appcompat-v7:$rootProject.ext.supportVersion"
|
implementation 'androidx.core:core:1.3.2'
|
||||||
implementation "com.android.support:design:$rootProject.ext.supportVersion"
|
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||||
implementation "com.android.support:support-v4:$rootProject.ext.supportVersion"
|
implementation 'com.google.android.material:material:1.3.0'
|
||||||
implementation "com.android.support:recyclerview-v7:$rootProject.ext.supportVersion"
|
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||||
implementation "com.android.support:cardview-v7:$rootProject.ext.supportVersion"
|
implementation 'androidx.recyclerview:recyclerview:1.1.0'
|
||||||
implementation "com.android.support:swiperefreshlayout:$rootProject.ext.supportVersion"
|
implementation 'androidx.cardview:cardview:1.0.0'
|
||||||
implementation "com.android.support.constraint:constraint-layout:$rootProject.ext.constraintVersion"
|
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.2.0-alpha01'
|
||||||
|
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
|
||||||
|
|
||||||
implementation 'me.dm7.barcodescanner:zxing:1.9.8'
|
implementation 'me.dm7.barcodescanner:zxing:1.9.8'
|
||||||
|
implementation "com.squareup.okhttp3:okhttp:4.9.0"
|
||||||
|
implementation "com.burgstaller:okhttp-digest:2.1"
|
||||||
|
implementation "com.jakewharton.timber:timber:4.7.1"
|
||||||
|
|
||||||
implementation "com.squareup.okhttp3:okhttp:$rootProject.ext.okHttpVersion"
|
implementation 'com.nulab-inc:zxcvbn:1.3.0'
|
||||||
implementation "com.burgstaller:okhttp-digest:1.18"
|
|
||||||
implementation "com.jakewharton.timber:timber:$rootProject.ext.timberVersion"
|
|
||||||
|
|
||||||
implementation 'com.nulab-inc:zxcvbn:1.2.3'
|
implementation 'dnsjava:dnsjava:2.1.9'
|
||||||
|
implementation 'org.jitsi:dnssecjava:1.2.0'
|
||||||
implementation 'dnsjava:dnsjava:2.1.8'
|
implementation 'org.slf4j:slf4j-nop:1.7.30'
|
||||||
implementation 'org.jitsi:dnssecjava:1.1.3'
|
|
||||||
implementation 'org.slf4j:slf4j-nop:1.7.25'
|
|
||||||
implementation 'com.github.brnunes:swipeablerecyclerview:1.0.2'
|
implementation 'com.github.brnunes:swipeablerecyclerview:1.0.2'
|
||||||
|
|
||||||
// https://mvnrepository.com/artifact/com.github.aelstad/keccakj
|
|
||||||
implementation 'com.github.aelstad:keccakj:1.1.0'
|
implementation 'com.github.aelstad:keccakj:1.1.0'
|
||||||
|
|
||||||
|
|
||||||
testImplementation "junit:junit:$rootProject.ext.junitVersion"
|
testImplementation "junit:junit:$rootProject.ext.junitVersion"
|
||||||
testImplementation "org.mockito:mockito-all:$rootProject.ext.mockitoVersion"
|
testImplementation "org.mockito:mockito-all:$rootProject.ext.mockitoVersion"
|
||||||
testImplementation "com.squareup.okhttp3:mockwebserver:$rootProject.ext.okHttpVersion"
|
testImplementation "com.squareup.okhttp3:mockwebserver:4.9.0"
|
||||||
testImplementation 'org.json:json:20180813'
|
testImplementation 'org.json:json:20180813'
|
||||||
testImplementation 'net.jodah:concurrentunit:0.4.4'
|
testImplementation 'net.jodah:concurrentunit:0.4.4'
|
||||||
|
|
||||||
|
compileOnly 'org.projectlombok:lombok:1.18.16'
|
||||||
|
annotationProcessor 'org.projectlombok:lombok:1.18.16'
|
||||||
}
|
}
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
|
android:requestLegacyExternalStorage="true"
|
||||||
android:name=".XmrWalletApplication"
|
android:name=".XmrWalletApplication"
|
||||||
android:allowBackup="false"
|
android:allowBackup="false"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
@@ -20,8 +21,9 @@
|
|||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/MyMaterialTheme"
|
android:theme="@style/MyMaterialTheme"
|
||||||
android:usesCleartextTraffic="true">
|
android:usesCleartextTraffic="true">
|
||||||
<activity android:name=".MainActivity"
|
<activity
|
||||||
android:configChanges="orientation|keyboardHidden"
|
android:name=".MainActivity"
|
||||||
|
android:configChanges="orientation|keyboardHidden|uiMode"
|
||||||
android:launchMode="singleTop"
|
android:launchMode="singleTop"
|
||||||
android:screenOrientation="portrait">
|
android:screenOrientation="portrait">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
@@ -31,13 +33,13 @@
|
|||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".WalletActivity"
|
android:name=".WalletActivity"
|
||||||
android:configChanges="orientation|keyboardHidden"
|
android:configChanges="orientation|keyboardHidden|uiMode"
|
||||||
android:label="@string/wallet_activity_name"
|
android:label="@string/wallet_activity_name"
|
||||||
android:launchMode="singleTask"
|
android:launchMode="singleTask"
|
||||||
android:screenOrientation="behind" />
|
android:screenOrientation="behind"/>
|
||||||
<activity
|
<activity
|
||||||
android:name=".LoginActivity"
|
android:name=".LoginActivity"
|
||||||
android:configChanges="orientation|keyboardHidden"
|
android:configChanges="orientation|keyboardHidden|uiMode"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:launchMode="singleTop"
|
android:launchMode="singleTop"
|
||||||
android:screenOrientation="locked">
|
android:screenOrientation="locked">
|
||||||
@@ -65,10 +67,11 @@
|
|||||||
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
|
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
|
||||||
android:resource="@xml/usb_device_filter" />
|
android:resource="@xml/usb_device_filter" />
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name=".onboarding.OnBoardingActivity"
|
<activity
|
||||||
android:configChanges="orientation|keyboardHidden"
|
android:name=".onboarding.OnBoardingActivity"
|
||||||
|
android:configChanges="orientation|keyboardHidden|uiMode"
|
||||||
android:launchMode="singleTask"
|
android:launchMode="singleTask"
|
||||||
android:screenOrientation="portrait"/>
|
android:screenOrientation="portrait" />
|
||||||
|
|
||||||
<service
|
<service
|
||||||
android:name=".service.WalletService"
|
android:name=".service.WalletService"
|
||||||
@@ -77,7 +80,7 @@
|
|||||||
android:label="Monero Wallet Service" />
|
android:label="Monero Wallet Service" />
|
||||||
|
|
||||||
<provider
|
<provider
|
||||||
android:name="android.support.v4.content.FileProvider"
|
android:name="androidx.core.content.FileProvider"
|
||||||
android:authorities="${applicationId}.fileprovider"
|
android:authorities="${applicationId}.fileprovider"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:grantUriPermissions="true">
|
android:grantUriPermissions="true">
|
||||||
|
@@ -185,7 +185,6 @@ public class Dispatcher implements PeerRetriever.OnGetPeers {
|
|||||||
|
|
||||||
public void seedPeers(Collection<NodeInfo> seedNodes) {
|
public void seedPeers(Collection<NodeInfo> seedNodes) {
|
||||||
for (NodeInfo node : seedNodes) {
|
for (NodeInfo node : seedNodes) {
|
||||||
node.clear();
|
|
||||||
if (node.isFavourite()) {
|
if (node.isFavourite()) {
|
||||||
rpcNodes.add(node);
|
rpcNodes.add(node);
|
||||||
if (listener != null) listener.onGet(node);
|
if (listener != null) listener.onGet(node);
|
||||||
|
@@ -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;
|
package com.m2049r.levin.scanner;
|
||||||
|
|
||||||
import java.net.InetAddress;
|
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;
|
package com.m2049r.xmrwallet;
|
||||||
|
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
@@ -15,9 +31,9 @@ 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.support.annotation.CallSuper;
|
import androidx.annotation.CallSuper;
|
||||||
import android.support.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import android.support.v4.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.data.BarcodeData;
|
import com.m2049r.xmrwallet.data.BarcodeData;
|
||||||
@@ -197,7 +213,7 @@ public class BaseActivity extends SecureActivity implements GenerateReviewFragme
|
|||||||
if (uri == null) {
|
if (uri == null) {
|
||||||
Toast.makeText(this, getString(R.string.nfc_tag_read_undef), Toast.LENGTH_LONG).show();
|
Toast.makeText(this, getString(R.string.nfc_tag_read_undef), Toast.LENGTH_LONG).show();
|
||||||
} else {
|
} else {
|
||||||
BarcodeData bc = BarcodeData.fromQrCode(uri.toString());
|
BarcodeData bc = BarcodeData.fromString(uri.toString());
|
||||||
if (bc == null)
|
if (bc == null)
|
||||||
Toast.makeText(this, getString(R.string.nfc_tag_read_undef), Toast.LENGTH_LONG).show();
|
Toast.makeText(this, getString(R.string.nfc_tag_read_undef), Toast.LENGTH_LONG).show();
|
||||||
else
|
else
|
||||||
|
@@ -17,13 +17,9 @@
|
|||||||
package com.m2049r.xmrwallet;
|
package com.m2049r.xmrwallet;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.support.design.widget.TextInputLayout;
|
|
||||||
import android.support.v4.app.Fragment;
|
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.Html;
|
import android.text.Html;
|
||||||
import android.text.InputType;
|
import android.text.InputType;
|
||||||
@@ -38,9 +34,15 @@ import android.view.WindowManager;
|
|||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.Switch;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
import com.google.android.material.switchmaterial.SwitchMaterial;
|
||||||
|
import com.google.android.material.textfield.TextInputLayout;
|
||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.model.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;
|
||||||
@@ -202,13 +204,13 @@ public class GenerateFragment extends Fragment {
|
|||||||
if (FingerprintHelper.isDeviceSupported(getContext())) {
|
if (FingerprintHelper.isDeviceSupported(getContext())) {
|
||||||
llFingerprintAuth.setVisibility(View.VISIBLE);
|
llFingerprintAuth.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
final Switch swFingerprintAllowed = (Switch) llFingerprintAuth.getChildAt(0);
|
final SwitchMaterial swFingerprintAllowed = (SwitchMaterial) llFingerprintAuth.getChildAt(0);
|
||||||
swFingerprintAllowed.setOnClickListener(new View.OnClickListener() {
|
swFingerprintAllowed.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
if (!swFingerprintAllowed.isChecked()) return;
|
if (!swFingerprintAllowed.isChecked()) return;
|
||||||
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getActivity());
|
||||||
builder.setMessage(Html.fromHtml(getString(R.string.generate_fingerprint_warn)))
|
builder.setMessage(Html.fromHtml(getString(R.string.generate_fingerprint_warn)))
|
||||||
.setCancelable(false)
|
.setCancelable(false)
|
||||||
.setPositiveButton(getString(R.string.label_ok), null)
|
.setPositiveButton(getString(R.string.label_ok), null)
|
||||||
@@ -507,7 +509,7 @@ public class GenerateFragment extends Fragment {
|
|||||||
|
|
||||||
String name = etWalletName.getEditText().getText().toString();
|
String name = etWalletName.getEditText().getText().toString();
|
||||||
String password = etWalletPassword.getEditText().getText().toString();
|
String password = etWalletPassword.getEditText().getText().toString();
|
||||||
boolean fingerprintAuthAllowed = ((Switch) llFingerprintAuth.getChildAt(0)).isChecked();
|
boolean fingerprintAuthAllowed = ((SwitchMaterial) llFingerprintAuth.getChildAt(0)).isChecked();
|
||||||
|
|
||||||
// create the real wallet password
|
// create the real wallet password
|
||||||
String crazyPass = KeyStoreHelper.getCrazyPass(getActivity(), password);
|
String crazyPass = KeyStoreHelper.getCrazyPass(getActivity(), password);
|
||||||
@@ -646,7 +648,7 @@ public class GenerateFragment extends Fragment {
|
|||||||
if (ledgerDialog != null) return;
|
if (ledgerDialog != null) return;
|
||||||
final Activity activity = getActivity();
|
final Activity activity = getActivity();
|
||||||
View promptsView = getLayoutInflater().inflate(R.layout.prompt_ledger_seed, null);
|
View promptsView = getLayoutInflater().inflate(R.layout.prompt_ledger_seed, null);
|
||||||
android.app.AlertDialog.Builder alertDialogBuilder = new android.app.AlertDialog.Builder(activity);
|
MaterialAlertDialogBuilder alertDialogBuilder = new MaterialAlertDialogBuilder(activity);
|
||||||
alertDialogBuilder.setView(promptsView);
|
alertDialogBuilder.setView(promptsView);
|
||||||
|
|
||||||
final TextInputLayout etSeed = promptsView.findViewById(R.id.etSeed);
|
final TextInputLayout etSeed = promptsView.findViewById(R.id.etSeed);
|
||||||
|
@@ -16,14 +16,10 @@
|
|||||||
|
|
||||||
package com.m2049r.xmrwallet;
|
package com.m2049r.xmrwallet;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.support.design.widget.TextInputLayout;
|
|
||||||
import android.support.v4.app.Fragment;
|
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.Html;
|
import android.text.Html;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
@@ -40,10 +36,17 @@ import android.widget.ImageButton;
|
|||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.ScrollView;
|
import android.widget.ScrollView;
|
||||||
import android.widget.Switch;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
import com.google.android.material.switchmaterial.SwitchMaterial;
|
||||||
|
import com.google.android.material.textfield.TextInputLayout;
|
||||||
import com.m2049r.xmrwallet.ledger.Ledger;
|
import com.m2049r.xmrwallet.ledger.Ledger;
|
||||||
import com.m2049r.xmrwallet.ledger.LedgerProgressDialog;
|
import com.m2049r.xmrwallet.ledger.LedgerProgressDialog;
|
||||||
import com.m2049r.xmrwallet.model.NetworkType;
|
import com.m2049r.xmrwallet.model.NetworkType;
|
||||||
@@ -118,31 +121,11 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
tvWalletSpendKey.setTextIsSelectable(allowCopy);
|
tvWalletSpendKey.setTextIsSelectable(allowCopy);
|
||||||
tvWalletPassword.setTextIsSelectable(allowCopy);
|
tvWalletPassword.setTextIsSelectable(allowCopy);
|
||||||
|
|
||||||
bAccept.setOnClickListener(new View.OnClickListener() {
|
bAccept.setOnClickListener(v -> acceptWallet());
|
||||||
@Override
|
view.findViewById(R.id.bCopyViewKey).setOnClickListener(v -> copyViewKey());
|
||||||
public void onClick(View v) {
|
bCopyAddress.setEnabled(false);
|
||||||
acceptWallet();
|
bCopyAddress.setOnClickListener(v -> copyAddress());
|
||||||
}
|
view.findViewById(R.id.bAdvancedInfo).setOnClickListener(v -> showAdvancedInfo());
|
||||||
});
|
|
||||||
view.findViewById(R.id.bCopyViewKey).setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
copyViewKey();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
bCopyAddress.setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
copyAddress();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
bCopyAddress.setClickable(false);
|
|
||||||
view.findViewById(R.id.bAdvancedInfo).setOnClickListener(new View.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
showAdvancedInfo();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Bundle args = getArguments();
|
Bundle args = getArguments();
|
||||||
type = args.getString(REQUEST_TYPE);
|
type = args.getString(REQUEST_TYPE);
|
||||||
@@ -287,8 +270,7 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
showAdvanced = true;
|
showAdvanced = true;
|
||||||
}
|
}
|
||||||
if (showAdvanced) bAdvancedInfo.setVisibility(View.VISIBLE);
|
if (showAdvanced) bAdvancedInfo.setVisibility(View.VISIBLE);
|
||||||
bCopyAddress.setClickable(true);
|
bCopyAddress.setEnabled(true);
|
||||||
bCopyAddress.setImageResource(R.drawable.ic_content_copy_black_24dp);
|
|
||||||
activityCallback.setTitle(name, getString(R.string.details_title));
|
activityCallback.setTitle(name, getString(R.string.details_title));
|
||||||
activityCallback.setToolbarButton(
|
activityCallback.setToolbarButton(
|
||||||
GenerateReviewFragment.VIEW_TYPE_ACCEPT.equals(type) ? Toolbar.BUTTON_NONE : Toolbar.BUTTON_BACK);
|
GenerateReviewFragment.VIEW_TYPE_ACCEPT.equals(type) ? Toolbar.BUTTON_NONE : Toolbar.BUTTON_BACK);
|
||||||
@@ -352,7 +334,7 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAttach(Context context) {
|
public void onAttach(@NonNull Context context) {
|
||||||
super.onAttach(context);
|
super.onAttach(context);
|
||||||
if (context instanceof Listener) {
|
if (context instanceof Listener) {
|
||||||
this.activityCallback = (Listener) context;
|
this.activityCallback = (Listener) context;
|
||||||
@@ -399,7 +381,7 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
|
||||||
String type = getArguments().getString(REQUEST_TYPE); // intance variable <type> not set yet
|
String type = getArguments().getString(REQUEST_TYPE); // intance variable <type> not set yet
|
||||||
if (GenerateReviewFragment.VIEW_TYPE_ACCEPT.equals(type)) {
|
if (GenerateReviewFragment.VIEW_TYPE_ACCEPT.equals(type)) {
|
||||||
inflater.inflate(R.menu.wallet_details_help_menu, menu);
|
inflater.inflate(R.menu.wallet_details_help_menu, menu);
|
||||||
@@ -448,7 +430,7 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
protected Boolean doInBackground(String... params) {
|
protected Boolean doInBackground(String... params) {
|
||||||
if (params.length != 2) return false;
|
if (params.length != 2) return false;
|
||||||
final String userPassword = params[0];
|
final String userPassword = params[0];
|
||||||
final boolean fingerPassValid = Boolean.valueOf(params[1]);
|
final boolean fingerPassValid = Boolean.parseBoolean(params[1]);
|
||||||
newPassword = KeyStoreHelper.getCrazyPass(getActivity(), userPassword);
|
newPassword = KeyStoreHelper.getCrazyPass(getActivity(), userPassword);
|
||||||
final boolean success = changeWalletPassword(newPassword);
|
final boolean success = changeWalletPassword(newPassword);
|
||||||
if (success) {
|
if (success) {
|
||||||
@@ -488,7 +470,7 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
LayoutInflater li = LayoutInflater.from(getActivity());
|
LayoutInflater li = LayoutInflater.from(getActivity());
|
||||||
View promptsView = li.inflate(R.layout.prompt_changepw, null);
|
View promptsView = li.inflate(R.layout.prompt_changepw, null);
|
||||||
|
|
||||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity());
|
AlertDialog.Builder alertDialogBuilder = new MaterialAlertDialogBuilder(getActivity());
|
||||||
alertDialogBuilder.setView(promptsView);
|
alertDialogBuilder.setView(promptsView);
|
||||||
|
|
||||||
final TextInputLayout etPasswordA = promptsView.findViewById(R.id.etWalletPasswordA);
|
final TextInputLayout etPasswordA = promptsView.findViewById(R.id.etWalletPasswordA);
|
||||||
@@ -498,7 +480,7 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
etPasswordB.setHint(getString(R.string.prompt_changepwB, walletName));
|
etPasswordB.setHint(getString(R.string.prompt_changepwB, walletName));
|
||||||
|
|
||||||
LinearLayout llFingerprintAuth = promptsView.findViewById(R.id.llFingerprintAuth);
|
LinearLayout llFingerprintAuth = promptsView.findViewById(R.id.llFingerprintAuth);
|
||||||
final Switch swFingerprintAllowed = (Switch) llFingerprintAuth.getChildAt(0);
|
final SwitchMaterial swFingerprintAllowed = (SwitchMaterial) llFingerprintAuth.getChildAt(0);
|
||||||
if (FingerprintHelper.isDeviceSupported(getActivity())) {
|
if (FingerprintHelper.isDeviceSupported(getActivity())) {
|
||||||
llFingerprintAuth.setVisibility(View.VISIBLE);
|
llFingerprintAuth.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
@@ -507,7 +489,7 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
if (!swFingerprintAllowed.isChecked()) return;
|
if (!swFingerprintAllowed.isChecked()) return;
|
||||||
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(getActivity());
|
||||||
builder.setMessage(Html.fromHtml(getString(R.string.generate_fingerprint_warn)))
|
builder.setMessage(Html.fromHtml(getString(R.string.generate_fingerprint_warn)))
|
||||||
.setCancelable(false)
|
.setCancelable(false)
|
||||||
.setPositiveButton(getString(R.string.label_ok), null)
|
.setPositiveButton(getString(R.string.label_ok), null)
|
||||||
@@ -596,7 +578,7 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
etPasswordA.setError(getString(R.string.generate_empty_passwordB));
|
etPasswordA.setError(getString(R.string.generate_empty_passwordB));
|
||||||
} else if (!newPasswordA.equals(newPasswordB)) {
|
} else if (!newPasswordA.equals(newPasswordB)) {
|
||||||
etPasswordB.setError(getString(R.string.generate_bad_passwordB));
|
etPasswordB.setError(getString(R.string.generate_bad_passwordB));
|
||||||
} else if (newPasswordA.equals(newPasswordB)) {
|
} else {
|
||||||
new AsyncChangePassword().execute(newPasswordA, Boolean.toString(swFingerprintAllowed.isChecked()));
|
new AsyncChangePassword().execute(newPasswordA, Boolean.toString(swFingerprintAllowed.isChecked()));
|
||||||
Helper.hideKeyboardAlways(getActivity());
|
Helper.hideKeyboardAlways(getActivity());
|
||||||
openDialog.dismiss();
|
openDialog.dismiss();
|
||||||
@@ -619,7 +601,7 @@ public class GenerateReviewFragment extends Fragment {
|
|||||||
etPasswordA.setError(getString(R.string.generate_empty_passwordB));
|
etPasswordA.setError(getString(R.string.generate_empty_passwordB));
|
||||||
} else if (!newPasswordA.equals(newPasswordB)) {
|
} else if (!newPasswordA.equals(newPasswordB)) {
|
||||||
etPasswordB.setError(getString(R.string.generate_bad_passwordB));
|
etPasswordB.setError(getString(R.string.generate_bad_passwordB));
|
||||||
} else if (newPasswordA.equals(newPasswordB)) {
|
} else {
|
||||||
new AsyncChangePassword().execute(newPasswordA, Boolean.toString(swFingerprintAllowed.isChecked()));
|
new AsyncChangePassword().execute(newPasswordA, Boolean.toString(swFingerprintAllowed.isChecked()));
|
||||||
Helper.hideKeyboardAlways(getActivity());
|
Helper.hideKeyboardAlways(getActivity());
|
||||||
openDialog.dismiss();
|
openDialog.dismiss();
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -19,11 +19,6 @@ package com.m2049r.xmrwallet;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.support.design.widget.FloatingActionButton;
|
|
||||||
import android.support.v4.app.Fragment;
|
|
||||||
import android.support.v7.widget.RecyclerView;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
@@ -38,12 +33,19 @@ import android.widget.RelativeLayout;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
import com.m2049r.xmrwallet.data.NodeInfo;
|
import com.m2049r.xmrwallet.data.NodeInfo;
|
||||||
import com.m2049r.xmrwallet.layout.NodeInfoAdapter;
|
import com.m2049r.xmrwallet.layout.NodeInfoAdapter;
|
||||||
import com.m2049r.xmrwallet.layout.WalletInfoAdapter;
|
import com.m2049r.xmrwallet.layout.WalletInfoAdapter;
|
||||||
import com.m2049r.xmrwallet.model.WalletManager;
|
import com.m2049r.xmrwallet.model.WalletManager;
|
||||||
import com.m2049r.xmrwallet.util.Helper;
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
import com.m2049r.xmrwallet.util.KeyStoreHelper;
|
import com.m2049r.xmrwallet.util.KeyStoreHelper;
|
||||||
|
import com.m2049r.xmrwallet.util.NodePinger;
|
||||||
import com.m2049r.xmrwallet.util.Notice;
|
import com.m2049r.xmrwallet.util.Notice;
|
||||||
import com.m2049r.xmrwallet.widget.Toolbar;
|
import com.m2049r.xmrwallet.widget.Toolbar;
|
||||||
|
|
||||||
@@ -63,6 +65,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
|||||||
private List<WalletManager.WalletInfo> walletList = new ArrayList<>();
|
private List<WalletManager.WalletInfo> walletList = new ArrayList<>();
|
||||||
private List<WalletManager.WalletInfo> displayedList = new ArrayList<>();
|
private List<WalletManager.WalletInfo> displayedList = new ArrayList<>();
|
||||||
|
|
||||||
|
private View tvGuntherSays;
|
||||||
private ImageView ivGunther;
|
private ImageView ivGunther;
|
||||||
private TextView tvNodeName;
|
private TextView tvNodeName;
|
||||||
private TextView tvNodeAddress;
|
private TextView tvNodeAddress;
|
||||||
@@ -103,6 +106,8 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
|||||||
|
|
||||||
Set<NodeInfo> getFavouriteNodes();
|
Set<NodeInfo> getFavouriteNodes();
|
||||||
|
|
||||||
|
Set<NodeInfo> getOrPopulateFavourites();
|
||||||
|
|
||||||
boolean hasLedger();
|
boolean hasLedger();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,11 +135,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
|||||||
activityCallback.setTitle(null);
|
activityCallback.setTitle(null);
|
||||||
activityCallback.setToolbarButton(Toolbar.BUTTON_CREDITS);
|
activityCallback.setToolbarButton(Toolbar.BUTTON_CREDITS);
|
||||||
activityCallback.showNet();
|
activityCallback.showNet();
|
||||||
NodeInfo node = activityCallback.getNode();
|
pingSelectedNode();
|
||||||
if (node == null)
|
|
||||||
findBestNode();
|
|
||||||
else
|
|
||||||
showNode(node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -143,6 +144,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
|||||||
Timber.d("onCreateView");
|
Timber.d("onCreateView");
|
||||||
View view = inflater.inflate(R.layout.fragment_login, container, false);
|
View view = inflater.inflate(R.layout.fragment_login, container, false);
|
||||||
|
|
||||||
|
tvGuntherSays = view.findViewById(R.id.tvGuntherSays);
|
||||||
ivGunther = view.findViewById(R.id.ivGunther);
|
ivGunther = view.findViewById(R.id.ivGunther);
|
||||||
fabScreen = view.findViewById(R.id.fabScreen);
|
fabScreen = view.findViewById(R.id.fabScreen);
|
||||||
fab = view.findViewById(R.id.fab);
|
fab = view.findViewById(R.id.fab);
|
||||||
@@ -183,23 +185,10 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
|||||||
|
|
||||||
pbNode = view.findViewById(R.id.pbNode);
|
pbNode = view.findViewById(R.id.pbNode);
|
||||||
llNode = view.findViewById(R.id.llNode);
|
llNode = view.findViewById(R.id.llNode);
|
||||||
llNode.setOnClickListener(new View.OnClickListener() {
|
llNode.setOnClickListener(v -> startNodePrefs());
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
if (activityCallback.getFavouriteNodes().isEmpty())
|
|
||||||
startNodePrefs();
|
|
||||||
else
|
|
||||||
findBestNode();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
tvNodeName = view.findViewById(R.id.tvNodeName);
|
tvNodeName = view.findViewById(R.id.tvNodeName);
|
||||||
tvNodeAddress = view.findViewById(R.id.tvNodeAddress);
|
tvNodeAddress = view.findViewById(R.id.tvNodeAddress);
|
||||||
view.findViewById(R.id.ibOption).setOnClickListener(new View.OnClickListener() {
|
view.findViewById(R.id.ibRenew).setOnClickListener(v -> findBestNode());
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
startNodePrefs();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Helper.hideKeyboard(getActivity());
|
Helper.hideKeyboard(getActivity());
|
||||||
|
|
||||||
@@ -275,13 +264,15 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
|||||||
if (displayedList.isEmpty()) {
|
if (displayedList.isEmpty()) {
|
||||||
fab.startAnimation(fab_pulse);
|
fab.startAnimation(fab_pulse);
|
||||||
if (ivGunther.getDrawable() == null) {
|
if (ivGunther.getDrawable() == null) {
|
||||||
ivGunther.setImageResource(R.drawable.gunther_desaturated);
|
ivGunther.setImageResource(R.drawable.ic_emptygunther);
|
||||||
|
tvGuntherSays.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fab.clearAnimation();
|
fab.clearAnimation();
|
||||||
if (ivGunther.getDrawable() != null) {
|
if (ivGunther.getDrawable() != null) {
|
||||||
ivGunther.setImageDrawable(null);
|
ivGunther.setImageDrawable(null);
|
||||||
}
|
}
|
||||||
|
tvGuntherSays.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove information of non-existent wallet
|
// remove information of non-existent wallet
|
||||||
@@ -416,32 +407,57 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void findBestNode() {
|
public void findBestNode() {
|
||||||
new AsyncFindBestNode().execute();
|
new AsyncFindBestNode().execute(AsyncFindBestNode.FIND_BEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class AsyncFindBestNode extends AsyncTask<Void, Void, NodeInfo> {
|
public void pingSelectedNode() {
|
||||||
|
new AsyncFindBestNode().execute(AsyncFindBestNode.PING_SELECTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
private NodeInfo autoselect(Set<NodeInfo> nodes) {
|
||||||
|
if (nodes.isEmpty()) return null;
|
||||||
|
NodePinger.execute(nodes, null);
|
||||||
|
List<NodeInfo> nodeList = new ArrayList<>(nodes);
|
||||||
|
Collections.sort(nodeList, NodeInfo.BestNodeComparator);
|
||||||
|
return nodeList.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class AsyncFindBestNode extends AsyncTask<Integer, Void, NodeInfo> {
|
||||||
|
final static int PING_SELECTED = 0;
|
||||||
|
final static int FIND_BEST = 1;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPreExecute() {
|
protected void onPreExecute() {
|
||||||
super.onPreExecute();
|
super.onPreExecute();
|
||||||
pbNode.setVisibility(View.VISIBLE);
|
pbNode.setVisibility(View.VISIBLE);
|
||||||
llNode.setVisibility(View.INVISIBLE);
|
llNode.setVisibility(View.INVISIBLE);
|
||||||
activityCallback.setNode(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected NodeInfo doInBackground(Void... params) {
|
protected NodeInfo doInBackground(Integer... params) {
|
||||||
List<NodeInfo> nodesToTest = new ArrayList<>(activityCallback.getFavouriteNodes());
|
Set<NodeInfo> favourites = activityCallback.getOrPopulateFavourites();
|
||||||
Timber.d("testing best node from %d", nodesToTest.size());
|
NodeInfo selectedNode;
|
||||||
if (nodesToTest.isEmpty()) return null;
|
if (params[0] == FIND_BEST) {
|
||||||
for (NodeInfo node : nodesToTest) {
|
selectedNode = autoselect(favourites);
|
||||||
node.testRpcService(); // TODO: do this in parallel?
|
} else if (params[0] == PING_SELECTED) {
|
||||||
// no: it's better if it looks like it's doing something
|
selectedNode = activityCallback.getNode();
|
||||||
}
|
if (!activityCallback.getFavouriteNodes().contains(selectedNode))
|
||||||
Collections.sort(nodesToTest, NodeInfo.BestNodeComparator);
|
selectedNode = null; // it's not in the favourites (any longer)
|
||||||
NodeInfo bestNode = nodesToTest.get(0);
|
if (selectedNode == null)
|
||||||
if (bestNode.isValid()) {
|
for (NodeInfo node : favourites) {
|
||||||
activityCallback.setNode(bestNode);
|
if (node.isSelected()) {
|
||||||
return bestNode;
|
selectedNode = node;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (selectedNode == null) { // autoselect
|
||||||
|
selectedNode = autoselect(favourites);
|
||||||
|
} else
|
||||||
|
selectedNode.testRpcService();
|
||||||
|
} else throw new IllegalStateException();
|
||||||
|
if ((selectedNode != null) && selectedNode.isValid()) {
|
||||||
|
activityCallback.setNode(selectedNode);
|
||||||
|
return selectedNode;
|
||||||
} else {
|
} else {
|
||||||
activityCallback.setNode(null);
|
activityCallback.setNode(null);
|
||||||
return null;
|
return null;
|
||||||
@@ -457,17 +473,10 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
|||||||
Timber.d("found a good node %s", result.toString());
|
Timber.d("found a good node %s", result.toString());
|
||||||
showNode(result);
|
showNode(result);
|
||||||
} else {
|
} else {
|
||||||
if (!activityCallback.getFavouriteNodes().isEmpty()) {
|
tvNodeName.setText(getResources().getText(R.string.node_create_hint));
|
||||||
tvNodeName.setText(getResources().getText(R.string.node_refresh_hint));
|
tvNodeName.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
|
||||||
tvNodeName.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_refresh_black_24dp, 0, 0, 0);
|
tvNodeAddress.setText(null);
|
||||||
tvNodeAddress.setText(null);
|
tvNodeAddress.setVisibility(View.GONE);
|
||||||
tvNodeAddress.setVisibility(View.GONE);
|
|
||||||
} else {
|
|
||||||
tvNodeName.setText(getResources().getText(R.string.node_create_hint));
|
|
||||||
tvNodeName.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
|
|
||||||
tvNodeAddress.setText(null);
|
|
||||||
tvNodeAddress.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -480,12 +489,11 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
|||||||
private void showNode(NodeInfo nodeInfo) {
|
private void showNode(NodeInfo nodeInfo) {
|
||||||
tvNodeName.setText(nodeInfo.getName());
|
tvNodeName.setText(nodeInfo.getName());
|
||||||
tvNodeName.setCompoundDrawablesWithIntrinsicBounds(NodeInfoAdapter.getPingIcon(nodeInfo), 0, 0, 0);
|
tvNodeName.setCompoundDrawablesWithIntrinsicBounds(NodeInfoAdapter.getPingIcon(nodeInfo), 0, 0, 0);
|
||||||
tvNodeAddress.setText(nodeInfo.getAddress());
|
Helper.showTimeDifference(tvNodeAddress, nodeInfo.getTimestamp());
|
||||||
tvNodeAddress.setVisibility(View.VISIBLE);
|
tvNodeAddress.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startNodePrefs() {
|
private void startNodePrefs() {
|
||||||
activityCallback.setNode(null);
|
|
||||||
activityCallback.onNodePrefs();
|
activityCallback.onNodePrefs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -18,13 +18,14 @@ package com.m2049r.xmrwallet;
|
|||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.onboarding.OnBoardingActivity;
|
import com.m2049r.xmrwallet.onboarding.OnBoardingActivity;
|
||||||
import com.m2049r.xmrwallet.onboarding.OnBoardingManager;
|
import com.m2049r.xmrwallet.onboarding.OnBoardingManager;
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity {
|
public class MainActivity extends BaseActivity {
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(@Nullable final Bundle savedInstanceState) {
|
protected void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -25,12 +25,6 @@ import android.net.Uri;
|
|||||||
import android.nfc.NfcManager;
|
import android.nfc.NfcManager;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.support.design.widget.TextInputLayout;
|
|
||||||
import android.support.v4.app.Fragment;
|
|
||||||
import android.support.v4.content.FileProvider;
|
|
||||||
import android.support.v4.view.MenuItemCompat;
|
|
||||||
import android.support.v7.widget.ShareActionProvider;
|
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.InputType;
|
import android.text.InputType;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
@@ -42,7 +36,6 @@ import android.view.MenuItem;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
@@ -50,13 +43,22 @@ import android.widget.ProgressBar;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.widget.ShareActionProvider;
|
||||||
|
import androidx.core.content.FileProvider;
|
||||||
|
import androidx.core.view.MenuItemCompat;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
|
import com.google.android.material.textfield.TextInputLayout;
|
||||||
import com.google.zxing.BarcodeFormat;
|
import com.google.zxing.BarcodeFormat;
|
||||||
import com.google.zxing.EncodeHintType;
|
import com.google.zxing.EncodeHintType;
|
||||||
import com.google.zxing.WriterException;
|
import com.google.zxing.WriterException;
|
||||||
import com.google.zxing.common.BitMatrix;
|
import com.google.zxing.common.BitMatrix;
|
||||||
import com.google.zxing.qrcode.QRCodeWriter;
|
import com.google.zxing.qrcode.QRCodeWriter;
|
||||||
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
|
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
|
||||||
|
import com.m2049r.xmrwallet.BuildConfig;
|
||||||
import com.m2049r.xmrwallet.data.BarcodeData;
|
import com.m2049r.xmrwallet.data.BarcodeData;
|
||||||
|
import com.m2049r.xmrwallet.data.Crypto;
|
||||||
import com.m2049r.xmrwallet.ledger.LedgerProgressDialog;
|
import com.m2049r.xmrwallet.ledger.LedgerProgressDialog;
|
||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.model.Wallet;
|
||||||
import com.m2049r.xmrwallet.model.WalletManager;
|
import com.m2049r.xmrwallet.model.WalletManager;
|
||||||
@@ -82,10 +84,11 @@ public class ReceiveFragment extends Fragment {
|
|||||||
private ExchangeView evAmount;
|
private ExchangeView evAmount;
|
||||||
private TextView tvQrCode;
|
private TextView tvQrCode;
|
||||||
private ImageView ivQrCode;
|
private ImageView ivQrCode;
|
||||||
|
private View cvQrCode;
|
||||||
private ImageView ivQrCodeFull;
|
private ImageView ivQrCodeFull;
|
||||||
private EditText etDummy;
|
private EditText etDummy;
|
||||||
private ImageButton bCopyAddress;
|
private ImageButton bCopyAddress;
|
||||||
private Button bSubaddress;
|
private ImageButton bSubaddress;
|
||||||
|
|
||||||
private Wallet wallet = null;
|
private Wallet wallet = null;
|
||||||
private boolean isMyWallet = false;
|
private boolean isMyWallet = false;
|
||||||
@@ -109,6 +112,7 @@ public class ReceiveFragment extends Fragment {
|
|||||||
tvAddress = view.findViewById(R.id.tvAddress);
|
tvAddress = view.findViewById(R.id.tvAddress);
|
||||||
etNotes = view.findViewById(R.id.etNotes);
|
etNotes = view.findViewById(R.id.etNotes);
|
||||||
evAmount = view.findViewById(R.id.evAmount);
|
evAmount = view.findViewById(R.id.evAmount);
|
||||||
|
cvQrCode = view.findViewById(R.id.cvQrCode);
|
||||||
ivQrCode = view.findViewById(R.id.qrCode);
|
ivQrCode = view.findViewById(R.id.qrCode);
|
||||||
tvQrCode = view.findViewById(R.id.tvQrCode);
|
tvQrCode = view.findViewById(R.id.tvQrCode);
|
||||||
ivQrCodeFull = view.findViewById(R.id.qrCodeFull);
|
ivQrCodeFull = view.findViewById(R.id.qrCodeFull);
|
||||||
@@ -118,13 +122,9 @@ public class ReceiveFragment extends Fragment {
|
|||||||
|
|
||||||
etDummy.setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
|
etDummy.setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
|
||||||
|
|
||||||
bCopyAddress.setOnClickListener(new View.OnClickListener() {
|
bCopyAddress.setOnClickListener(v -> copyAddress());
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
copyAddress();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
enableCopyAddress(false);
|
enableCopyAddress(false);
|
||||||
|
enableSubaddressButton(false);
|
||||||
|
|
||||||
evAmount.setOnNewAmountListener(new ExchangeView.OnNewAmountListener() {
|
evAmount.setOnNewAmountListener(new ExchangeView.OnNewAmountListener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -190,7 +190,7 @@ public class ReceiveFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ivQrCode.setOnClickListener(new View.OnClickListener() {
|
cvQrCode.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
Helper.hideKeyboard(getActivity());
|
Helper.hideKeyboard(getActivity());
|
||||||
@@ -315,13 +315,8 @@ public class ReceiveFragment extends Fragment {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void enableSubaddressButton(boolean enable) {
|
private void enableSubaddressButton(boolean enable) {
|
||||||
bSubaddress.setEnabled(enable);
|
bSubaddress.setEnabled(enable);
|
||||||
if (enable) {
|
|
||||||
bSubaddress.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.ic_settings_orange_24dp, 0, 0);
|
|
||||||
} else {
|
|
||||||
bSubaddress.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.ic_settings_gray_24dp, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void copyAddress() {
|
void copyAddress() {
|
||||||
@@ -371,16 +366,13 @@ public class ReceiveFragment extends Fragment {
|
|||||||
listenerCallback.setSubtitle(wallet.getAccountLabel());
|
listenerCallback.setSubtitle(wallet.getAccountLabel());
|
||||||
tvAddress.setText(wallet.getAddress());
|
tvAddress.setText(wallet.getAddress());
|
||||||
enableCopyAddress(true);
|
enableCopyAddress(true);
|
||||||
|
enableSubaddressButton(true);
|
||||||
hideProgress();
|
hideProgress();
|
||||||
generateQr();
|
generateQr();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void enableCopyAddress(boolean enable) {
|
private void enableCopyAddress(boolean enable) {
|
||||||
bCopyAddress.setClickable(enable);
|
bCopyAddress.setEnabled(enable);
|
||||||
if (enable)
|
|
||||||
bCopyAddress.setImageResource(R.drawable.ic_content_copy_black_24dp);
|
|
||||||
else
|
|
||||||
bCopyAddress.setImageResource(R.drawable.ic_content_nocopy_black_24dp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadAndShow(String walletPath, String password) {
|
private void loadAndShow(String walletPath, String password) {
|
||||||
@@ -478,7 +470,7 @@ public class ReceiveFragment extends Fragment {
|
|||||||
Timber.d("CLEARQR");
|
Timber.d("CLEARQR");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bcData = new BarcodeData(BarcodeData.Asset.XMR, address, null, notes, xmrAmount);
|
bcData = new BarcodeData(Crypto.XMR, address, notes, xmrAmount);
|
||||||
int size = Math.max(ivQrCode.getWidth(), ivQrCode.getHeight());
|
int size = Math.max(ivQrCode.getWidth(), ivQrCode.getHeight());
|
||||||
Bitmap qr = generate(bcData.getUriString(), size, size);
|
Bitmap qr = generate(bcData.getUriString(), size, size);
|
||||||
if (qr != null) {
|
if (qr != null) {
|
||||||
@@ -620,6 +612,8 @@ public class ReceiveFragment extends Fragment {
|
|||||||
super.onPostExecute(result);
|
super.onPostExecute(result);
|
||||||
if (dialogOpened)
|
if (dialogOpened)
|
||||||
progressCallback.dismissProgressDialog();
|
progressCallback.dismissProgressDialog();
|
||||||
|
if (!isAdded()) // never mind then
|
||||||
|
return;
|
||||||
tvAddress.setText(newSubaddress);
|
tvAddress.setText(newSubaddress);
|
||||||
tvAddressLabel.setText(getString(R.string.generate_address_label_sub,
|
tvAddressLabel.setText(getString(R.string.generate_address_label_sub,
|
||||||
wallet.getNumSubaddresses() - 1));
|
wallet.getNumSubaddresses() - 1));
|
||||||
|
@@ -19,7 +19,7 @@ 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 android.support.v4.app.Fragment;
|
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;
|
||||||
@@ -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.
|
// * 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.
|
// * I don't know why this is the case but I don't have the time to figure out.
|
||||||
Handler handler = new Handler();
|
Handler handler = new Handler();
|
||||||
handler.postDelayed(new
|
handler.postDelayed(() -> mScannerView.resumeCameraPreview(ScannerFragment.this), 2000);
|
||||||
|
|
||||||
Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
mScannerView.resumeCameraPreview(ScannerFragment.this);
|
|
||||||
}
|
|
||||||
}, 2000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -17,13 +17,18 @@
|
|||||||
package com.m2049r.xmrwallet;
|
package com.m2049r.xmrwallet;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.util.Helper;
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
import com.m2049r.xmrwallet.util.LocaleHelper;
|
import com.m2049r.xmrwallet.util.LocaleHelper;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
import static android.view.WindowManager.LayoutParams;
|
import static android.view.WindowManager.LayoutParams;
|
||||||
|
|
||||||
public abstract class SecureActivity extends AppCompatActivity {
|
public abstract class SecureActivity extends AppCompatActivity {
|
||||||
@@ -37,7 +42,36 @@ public abstract class SecureActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void attachBaseContext(Context context) {
|
protected void attachBaseContext(Context newBase) {
|
||||||
super.attachBaseContext(LocaleHelper.setLocale(context, LocaleHelper.getLocale(context)));
|
super.attachBaseContext(newBase);
|
||||||
|
applyOverrideConfiguration(new Configuration());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyOverrideConfiguration(Configuration newConfig) {
|
||||||
|
super.applyOverrideConfiguration(updateConfigurationIfSupported(newConfig));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Configuration updateConfigurationIfSupported(Configuration config) {
|
||||||
|
// Configuration.getLocales is added after 24 and Configuration.locale is deprecated in 24
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
|
if (!config.getLocales().isEmpty()) {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (config.locale != null) {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Locale locale = LocaleHelper.getPreferredLocale(this);
|
||||||
|
if (locale != null) {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||||
|
config.setLocale(locale);
|
||||||
|
} else {
|
||||||
|
config.locale = locale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return config;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,27 +16,31 @@
|
|||||||
|
|
||||||
package com.m2049r.xmrwallet;
|
package com.m2049r.xmrwallet;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.support.v4.app.Fragment;
|
|
||||||
import android.support.v4.content.ContextCompat;
|
|
||||||
import android.text.InputType;
|
import android.text.InputType;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.data.UserNotes;
|
||||||
import com.m2049r.xmrwallet.model.TransactionInfo;
|
import com.m2049r.xmrwallet.model.TransactionInfo;
|
||||||
import com.m2049r.xmrwallet.model.Transfer;
|
import com.m2049r.xmrwallet.model.Transfer;
|
||||||
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.data.UserNotes;
|
|
||||||
import com.m2049r.xmrwallet.widget.Toolbar;
|
import com.m2049r.xmrwallet.widget.Toolbar;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
@@ -77,6 +81,9 @@ public class TxFragment extends Fragment {
|
|||||||
private TextView tvTxXmrToKey;
|
private TextView tvTxXmrToKey;
|
||||||
private TextView tvDestinationBtc;
|
private TextView tvDestinationBtc;
|
||||||
private TextView tvTxAmountBtc;
|
private TextView tvTxAmountBtc;
|
||||||
|
private TextView tvXmrToSupport;
|
||||||
|
private TextView tvXmrToKeyLabel;
|
||||||
|
private ImageView tvXmrToLogo;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
@@ -88,6 +95,9 @@ public class TxFragment extends Fragment {
|
|||||||
tvTxXmrToKey = view.findViewById(R.id.tvTxXmrToKey);
|
tvTxXmrToKey = view.findViewById(R.id.tvTxXmrToKey);
|
||||||
tvDestinationBtc = view.findViewById(R.id.tvDestinationBtc);
|
tvDestinationBtc = view.findViewById(R.id.tvDestinationBtc);
|
||||||
tvTxAmountBtc = view.findViewById(R.id.tvTxAmountBtc);
|
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);
|
tvAccount = view.findViewById(R.id.tvAccount);
|
||||||
tvAddress = view.findViewById(R.id.tvAddress);
|
tvAddress = view.findViewById(R.id.tvAddress);
|
||||||
@@ -104,12 +114,9 @@ public class TxFragment extends Fragment {
|
|||||||
|
|
||||||
etTxNotes.setRawInputType(InputType.TYPE_CLASS_TEXT);
|
etTxNotes.setRawInputType(InputType.TYPE_CLASS_TEXT);
|
||||||
|
|
||||||
tvTxXmrToKey.setOnClickListener(new View.OnClickListener() {
|
tvTxXmrToKey.setOnClickListener(v -> {
|
||||||
@Override
|
Helper.clipBoardCopy(getActivity(), getString(R.string.label_copy_xmrtokey), tvTxXmrToKey.getText().toString());
|
||||||
public void onClick(View v) {
|
Toast.makeText(getActivity(), getString(R.string.message_copy_xmrtokey), Toast.LENGTH_SHORT).show();
|
||||||
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();
|
Bundle args = getArguments();
|
||||||
@@ -242,9 +249,9 @@ public class TxFragment extends Fragment {
|
|||||||
} else if (info.isPending) {
|
} else if (info.isPending) {
|
||||||
setTxColour(ContextCompat.getColor(getContext(), R.color.tx_pending));
|
setTxColour(ContextCompat.getColor(getContext(), R.color.tx_pending));
|
||||||
} else if (info.direction == TransactionInfo.Direction.Direction_In) {
|
} else if (info.direction == TransactionInfo.Direction.Direction_In) {
|
||||||
setTxColour(ContextCompat.getColor(getContext(), R.color.tx_green));
|
setTxColour(ContextCompat.getColor(getContext(), R.color.tx_plus));
|
||||||
} else {
|
} else {
|
||||||
setTxColour(ContextCompat.getColor(getContext(), R.color.tx_red));
|
setTxColour(ContextCompat.getColor(getContext(), R.color.tx_minus));
|
||||||
}
|
}
|
||||||
Set<String> destinations = new HashSet<>();
|
Set<String> destinations = new HashSet<>();
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuffer sb = new StringBuffer();
|
||||||
@@ -283,12 +290,36 @@ public class TxFragment extends Fragment {
|
|||||||
showBtcInfo();
|
showBtcInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
void showBtcInfo() {
|
void showBtcInfo() {
|
||||||
if (userNotes.xmrtoKey != null) {
|
if (userNotes.xmrtoKey != null) {
|
||||||
cvXmrTo.setVisibility(View.VISIBLE);
|
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);
|
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 {
|
} else {
|
||||||
cvXmrTo.setVisibility(View.GONE);
|
cvXmrTo.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package com.m2049r.xmrwallet;
|
package com.m2049r.xmrwallet;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
@@ -27,14 +26,6 @@ import android.content.pm.PackageManager;
|
|||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.support.design.widget.NavigationView;
|
|
||||||
import android.support.v4.app.Fragment;
|
|
||||||
import android.support.v4.app.FragmentManager;
|
|
||||||
import android.support.v4.app.FragmentTransaction;
|
|
||||||
import android.support.v4.view.GravityCompat;
|
|
||||||
import android.support.v4.widget.DrawerLayout;
|
|
||||||
import android.support.v7.app.ActionBarDrawerToggle;
|
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
@@ -45,6 +36,17 @@ import android.widget.EditText;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.app.ActionBarDrawerToggle;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.core.view.GravityCompat;
|
||||||
|
import androidx.drawerlayout.widget.DrawerLayout;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
import androidx.fragment.app.FragmentTransaction;
|
||||||
|
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
import com.google.android.material.navigation.NavigationView;
|
||||||
import com.m2049r.xmrwallet.data.BarcodeData;
|
import com.m2049r.xmrwallet.data.BarcodeData;
|
||||||
import com.m2049r.xmrwallet.data.TxData;
|
import com.m2049r.xmrwallet.data.TxData;
|
||||||
import com.m2049r.xmrwallet.data.UserNotes;
|
import com.m2049r.xmrwallet.data.UserNotes;
|
||||||
@@ -58,6 +60,7 @@ import com.m2049r.xmrwallet.model.TransactionInfo;
|
|||||||
import com.m2049r.xmrwallet.model.Wallet;
|
import com.m2049r.xmrwallet.model.Wallet;
|
||||||
import com.m2049r.xmrwallet.model.WalletManager;
|
import com.m2049r.xmrwallet.model.WalletManager;
|
||||||
import com.m2049r.xmrwallet.service.WalletService;
|
import com.m2049r.xmrwallet.service.WalletService;
|
||||||
|
import com.m2049r.xmrwallet.util.ColorHelper;
|
||||||
import com.m2049r.xmrwallet.util.Helper;
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
import com.m2049r.xmrwallet.util.MoneroThreadPoolExecutor;
|
import com.m2049r.xmrwallet.util.MoneroThreadPoolExecutor;
|
||||||
import com.m2049r.xmrwallet.widget.Toolbar;
|
import com.m2049r.xmrwallet.widget.Toolbar;
|
||||||
@@ -149,11 +152,9 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
|||||||
getSupportFragmentManager().findFragmentByTag(WalletFragment.class.getName());
|
getSupportFragmentManager().findFragmentByTag(WalletFragment.class.getName());
|
||||||
if (walletFragment != null) walletFragment.resetDismissedTransactions();
|
if (walletFragment != null) walletFragment.resetDismissedTransactions();
|
||||||
forceUpdate();
|
forceUpdate();
|
||||||
runOnUiThread(new Runnable() {
|
runOnUiThread(() -> {
|
||||||
@Override
|
if (getWallet() != null)
|
||||||
public void run() {
|
|
||||||
updateAccountsBalance();
|
updateAccountsBalance();
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,11 +315,6 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateStreetMode() {
|
private void updateStreetMode() {
|
||||||
if (isStreetMode()) {
|
|
||||||
toolbar.setBackgroundResource(R.drawable.backgound_toolbar_streetmode);
|
|
||||||
} else {
|
|
||||||
showNet();
|
|
||||||
}
|
|
||||||
invalidateOptionsMenu();
|
invalidateOptionsMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -428,10 +424,10 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
|||||||
toolbar.setBackgroundResource(R.drawable.backgound_toolbar_mainnet);
|
toolbar.setBackgroundResource(R.drawable.backgound_toolbar_mainnet);
|
||||||
break;
|
break;
|
||||||
case NetworkType_Testnet:
|
case NetworkType_Testnet:
|
||||||
toolbar.setBackgroundResource(R.color.colorPrimaryDark);
|
toolbar.setBackgroundResource(ColorHelper.getThemedResourceId(this, R.attr.colorPrimaryDark));
|
||||||
break;
|
break;
|
||||||
case NetworkType_Stagenet:
|
case NetworkType_Stagenet:
|
||||||
toolbar.setBackgroundResource(R.color.colorPrimaryDark);
|
toolbar.setBackgroundResource(ColorHelper.getThemedResourceId(this, R.attr.colorPrimaryDark));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException("Unsupported Network: " + WalletManager.getInstance().getNetworkType());
|
throw new IllegalStateException("Unsupported Network: " + WalletManager.getInstance().getNetworkType());
|
||||||
@@ -577,18 +573,13 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
|||||||
@Override
|
@Override
|
||||||
public boolean onRefreshed(final Wallet wallet, final boolean full) {
|
public boolean onRefreshed(final Wallet wallet, final boolean full) {
|
||||||
Timber.d("onRefreshed()");
|
Timber.d("onRefreshed()");
|
||||||
runOnUiThread(new Runnable() {
|
runOnUiThread(() -> {
|
||||||
public void run() {
|
if (getWallet() != null)
|
||||||
updateAccountsBalance();
|
updateAccountsBalance();
|
||||||
}
|
|
||||||
});
|
});
|
||||||
if (numAccounts != wallet.getNumAccounts()) {
|
if (numAccounts != wallet.getNumAccounts()) {
|
||||||
numAccounts = wallet.getNumAccounts();
|
numAccounts = wallet.getNumAccounts();
|
||||||
runOnUiThread(new Runnable() {
|
runOnUiThread(this::updateAccountsList);
|
||||||
public void run() {
|
|
||||||
updateAccountsList();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
final WalletFragment walletFragment = (WalletFragment)
|
final WalletFragment walletFragment = (WalletFragment)
|
||||||
@@ -670,7 +661,7 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
|||||||
haveWallet = true;
|
haveWallet = true;
|
||||||
invalidateOptionsMenu();
|
invalidateOptionsMenu();
|
||||||
|
|
||||||
enableStreetMode(requestStreetMode);
|
if (requestStreetMode) onEnableStreetMode();
|
||||||
|
|
||||||
final WalletFragment walletFragment = (WalletFragment)
|
final WalletFragment walletFragment = (WalletFragment)
|
||||||
getSupportFragmentManager().findFragmentById(R.id.fragment_container);
|
getSupportFragmentManager().findFragmentById(R.id.fragment_container);
|
||||||
@@ -875,7 +866,7 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
AlertDialog.Builder builder = new MaterialAlertDialogBuilder(this);
|
||||||
builder.setMessage(getString(R.string.details_alert_message))
|
builder.setMessage(getString(R.string.details_alert_message))
|
||||||
.setPositiveButton(getString(R.string.details_alert_yes), dialogClickListener)
|
.setPositiveButton(getString(R.string.details_alert_yes), dialogClickListener)
|
||||||
.setNegativeButton(getString(R.string.details_alert_no), dialogClickListener)
|
.setNegativeButton(getString(R.string.details_alert_no), dialogClickListener)
|
||||||
@@ -930,7 +921,7 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
|||||||
@Override
|
@Override
|
||||||
public boolean onScanned(String qrCode) {
|
public boolean onScanned(String qrCode) {
|
||||||
// #gurke
|
// #gurke
|
||||||
BarcodeData bcData = BarcodeData.fromQrCode(qrCode);
|
BarcodeData bcData = BarcodeData.fromString(qrCode);
|
||||||
if (bcData != null) {
|
if (bcData != null) {
|
||||||
popFragmentStack(null);
|
popFragmentStack(null);
|
||||||
Timber.d("AAA");
|
Timber.d("AAA");
|
||||||
@@ -1060,21 +1051,23 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
|||||||
}
|
}
|
||||||
|
|
||||||
void updateAccountsList() {
|
void updateAccountsList() {
|
||||||
final Wallet wallet = getWallet();
|
|
||||||
Menu menu = accountsView.getMenu();
|
Menu menu = accountsView.getMenu();
|
||||||
menu.removeGroup(R.id.accounts_list);
|
menu.removeGroup(R.id.accounts_list);
|
||||||
final int n = wallet.getNumAccounts();
|
final Wallet wallet = getWallet();
|
||||||
final boolean showBalances = (n > 1) && !isStreetMode();
|
if (wallet != null) {
|
||||||
for (int i = 0; i < n; i++) {
|
final int n = wallet.getNumAccounts();
|
||||||
final String label = (showBalances ?
|
final boolean showBalances = (n > 1) && !isStreetMode();
|
||||||
getString(R.string.label_account, wallet.getAccountLabel(i), Helper.getDisplayAmount(wallet.getBalance(i), 2))
|
for (int i = 0; i < n; i++) {
|
||||||
: wallet.getAccountLabel(i));
|
final String label = (showBalances ?
|
||||||
final MenuItem item = menu.add(R.id.accounts_list, getAccountId(i), 2 * i, label);
|
getString(R.string.label_account, wallet.getAccountLabel(i), Helper.getDisplayAmount(wallet.getBalance(i), 2))
|
||||||
item.setIcon(R.drawable.ic_account_balance_wallet_black_24dp);
|
: wallet.getAccountLabel(i));
|
||||||
if (i == wallet.getAccountIndex())
|
final MenuItem item = menu.add(R.id.accounts_list, getAccountId(i), 2 * i, label);
|
||||||
item.setChecked(true);
|
item.setIcon(R.drawable.ic_account_balance_wallet_black_24dp);
|
||||||
|
if (i == wallet.getAccountIndex())
|
||||||
|
item.setChecked(true);
|
||||||
|
}
|
||||||
|
menu.setGroupCheckable(R.id.accounts_list, true, true);
|
||||||
}
|
}
|
||||||
menu.setGroupCheckable(R.id.accounts_list, true, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1096,7 +1089,7 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
|
|||||||
final LayoutInflater li = LayoutInflater.from(this);
|
final LayoutInflater li = LayoutInflater.from(this);
|
||||||
final View promptsView = li.inflate(R.layout.prompt_rename, null);
|
final View promptsView = li.inflate(R.layout.prompt_rename, null);
|
||||||
|
|
||||||
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
|
final AlertDialog.Builder alertDialogBuilder = new MaterialAlertDialogBuilder(this);
|
||||||
alertDialogBuilder.setView(promptsView);
|
alertDialogBuilder.setView(promptsView);
|
||||||
|
|
||||||
final EditText etRename = promptsView.findViewById(R.id.etRename);
|
final EditText etRename = promptsView.findViewById(R.id.etRename);
|
||||||
|
@@ -17,12 +17,10 @@
|
|||||||
package com.m2049r.xmrwallet;
|
package com.m2049r.xmrwallet;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.support.v4.app.Fragment;
|
|
||||||
import android.support.v7.widget.RecyclerView;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
@@ -38,6 +36,11 @@ import android.widget.ProgressBar;
|
|||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.github.brnunes.swipeablerecyclerview.SwipeableRecyclerViewTouchListener;
|
import com.github.brnunes.swipeablerecyclerview.SwipeableRecyclerViewTouchListener;
|
||||||
import com.m2049r.xmrwallet.layout.TransactionInfoAdapter;
|
import com.m2049r.xmrwallet.layout.TransactionInfoAdapter;
|
||||||
import com.m2049r.xmrwallet.model.TransactionInfo;
|
import com.m2049r.xmrwallet.model.TransactionInfo;
|
||||||
@@ -46,6 +49,7 @@ import com.m2049r.xmrwallet.service.exchange.api.ExchangeApi;
|
|||||||
import com.m2049r.xmrwallet.service.exchange.api.ExchangeCallback;
|
import com.m2049r.xmrwallet.service.exchange.api.ExchangeCallback;
|
||||||
import com.m2049r.xmrwallet.service.exchange.api.ExchangeRate;
|
import com.m2049r.xmrwallet.service.exchange.api.ExchangeRate;
|
||||||
import com.m2049r.xmrwallet.util.Helper;
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
|
import com.m2049r.xmrwallet.util.ServiceHelper;
|
||||||
import com.m2049r.xmrwallet.widget.Toolbar;
|
import com.m2049r.xmrwallet.widget.Toolbar;
|
||||||
|
|
||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
@@ -70,6 +74,8 @@ public class WalletFragment extends Fragment
|
|||||||
private ProgressBar pbProgress;
|
private ProgressBar pbProgress;
|
||||||
private Button bReceive;
|
private Button bReceive;
|
||||||
private Button bSend;
|
private Button bSend;
|
||||||
|
private ImageView ivStreetGunther;
|
||||||
|
private Drawable streetGunther = null;
|
||||||
|
|
||||||
private Spinner sCurrency;
|
private Spinner sCurrency;
|
||||||
|
|
||||||
@@ -97,11 +103,12 @@ public class WalletFragment extends Fragment
|
|||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.fragment_wallet, container, false);
|
View view = inflater.inflate(R.layout.fragment_wallet, container, false);
|
||||||
|
|
||||||
|
ivStreetGunther = view.findViewById(R.id.ivStreetGunther);
|
||||||
tvStreetView = view.findViewById(R.id.tvStreetView);
|
tvStreetView = view.findViewById(R.id.tvStreetView);
|
||||||
llBalance = view.findViewById(R.id.llBalance);
|
llBalance = view.findViewById(R.id.llBalance);
|
||||||
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(getResources().getColor(R.color.trafficGray),
|
setColorFilter(getResources().getColor(R.color.progress_circle),
|
||||||
android.graphics.PorterDuff.Mode.MULTIPLY);
|
android.graphics.PorterDuff.Mode.MULTIPLY);
|
||||||
|
|
||||||
tvProgress = view.findViewById(R.id.tvProgress);
|
tvProgress = view.findViewById(R.id.tvProgress);
|
||||||
@@ -199,13 +206,15 @@ public class WalletFragment extends Fragment
|
|||||||
|
|
||||||
void showBalance(String balance) {
|
void showBalance(String balance) {
|
||||||
tvBalance.setText(balance);
|
tvBalance.setText(balance);
|
||||||
if (!activityCallback.isStreetMode()) {
|
final boolean streetMode = activityCallback.isStreetMode();
|
||||||
|
if (!streetMode) {
|
||||||
llBalance.setVisibility(View.VISIBLE);
|
llBalance.setVisibility(View.VISIBLE);
|
||||||
tvStreetView.setVisibility(View.INVISIBLE);
|
tvStreetView.setVisibility(View.INVISIBLE);
|
||||||
} else {
|
} else {
|
||||||
llBalance.setVisibility(View.INVISIBLE);
|
llBalance.setVisibility(View.INVISIBLE);
|
||||||
tvStreetView.setVisibility(View.VISIBLE);
|
tvStreetView.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
setStreetModeBackground(streetMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void showUnconfirmed(double unconfirmedAmount) {
|
void showUnconfirmed(double unconfirmedAmount) {
|
||||||
@@ -234,7 +243,7 @@ public class WalletFragment extends Fragment
|
|||||||
String balanceCurrency = Helper.BASE_CRYPTO;
|
String balanceCurrency = Helper.BASE_CRYPTO;
|
||||||
double balanceRate = 1.0;
|
double balanceRate = 1.0;
|
||||||
|
|
||||||
private final ExchangeApi exchangeApi = Helper.getExchangeApi();
|
private final ExchangeApi exchangeApi = ServiceHelper.getExchangeApi();
|
||||||
|
|
||||||
void refreshBalance() {
|
void refreshBalance() {
|
||||||
double unconfirmedXmr = Helper.getDecimalAmount(balance - unlockedBalance).doubleValue();
|
double unconfirmedXmr = Helper.getDecimalAmount(balance - unlockedBalance).doubleValue();
|
||||||
@@ -537,4 +546,13 @@ public class WalletFragment extends Fragment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setStreetModeBackground(boolean enable) {
|
||||||
|
//TODO figure out why gunther disappears on return from send although he is still set
|
||||||
|
if (enable) {
|
||||||
|
if (streetGunther == null)
|
||||||
|
streetGunther = ContextCompat.getDrawable(getContext(), R.drawable.ic_gunther_streetmode);
|
||||||
|
ivStreetGunther.setImageDrawable(streetGunther);
|
||||||
|
} else
|
||||||
|
ivStreetGunther.setImageDrawable(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,13 +16,15 @@
|
|||||||
|
|
||||||
package com.m2049r.xmrwallet;
|
package com.m2049r.xmrwallet;
|
||||||
|
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.BuildConfig;
|
||||||
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.NightmodeHelper;
|
||||||
|
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
@@ -34,18 +36,23 @@ public class XmrWalletApplication extends Application {
|
|||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
Timber.plant(new Timber.DebugTree());
|
Timber.plant(new Timber.DebugTree());
|
||||||
}
|
}
|
||||||
|
NightmodeHelper.setPreferredNightmode(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void attachBaseContext(Context context) {
|
protected void attachBaseContext(Context context) {
|
||||||
super.attachBaseContext(LocaleHelper.setLocale(context, LocaleHelper.getLocale(context)));
|
super.attachBaseContext(LocaleHelper.setPreferredLocale(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConfigurationChanged(Configuration configuration) {
|
public void onConfigurationChanged(Configuration configuration) {
|
||||||
super.onConfigurationChanged(configuration);
|
super.onConfigurationChanged(configuration);
|
||||||
LocaleHelper.updateSystemDefaultLocale(configuration.locale);
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
LocaleHelper.setLocale(XmrWalletApplication.this, LocaleHelper.getLocale(XmrWalletApplication.this));
|
LocaleHelper.updateSystemDefaultLocale(configuration.getLocales().get(0));
|
||||||
|
} else {
|
||||||
|
LocaleHelper.updateSystemDefaultLocale(configuration.locale);
|
||||||
|
}
|
||||||
|
LocaleHelper.setPreferredLocale(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public NetworkType getNetworkType() {
|
static public NetworkType getNetworkType() {
|
||||||
@@ -54,7 +61,7 @@ public class XmrWalletApplication extends Application {
|
|||||||
return NetworkType.NetworkType_Mainnet;
|
return NetworkType.NetworkType_Mainnet;
|
||||||
case "stagenet":
|
case "stagenet":
|
||||||
return NetworkType.NetworkType_Stagenet;
|
return NetworkType.NetworkType_Stagenet;
|
||||||
case "testnet":
|
case "devnet": // flavors cannot start with "test"
|
||||||
return NetworkType.NetworkType_Testnet;
|
return NetworkType.NetworkType_Testnet;
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException("unknown net flavor " + BuildConfig.FLAVOR_net);
|
throw new IllegalStateException("unknown net flavor " + BuildConfig.FLAVOR_net);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
// Nodes stolen from https://moneroworld.com/#nodes
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum DefaultNodes {
|
||||||
|
MONERUJO("nodex.monerujo.io:18081"),
|
||||||
|
XMRTO("node.xmr.to:18081"),
|
||||||
|
SUPPORTXMR("node.supportxmr.com:18081"),
|
||||||
|
HASHVAULT("nodes.hashvault.pro:18081"),
|
||||||
|
MONEROWORLD("node.moneroworld.com:18089"),
|
||||||
|
XMRTW("opennode.xmr-tw.org:18089");
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final String uri;
|
||||||
|
}
|
@@ -26,6 +26,8 @@ import java.net.URLDecoder;
|
|||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
public class Node {
|
public class Node {
|
||||||
@@ -33,15 +35,29 @@ public class Node {
|
|||||||
static public final String STAGENET = "stagenet";
|
static public final String STAGENET = "stagenet";
|
||||||
static public final String TESTNET = "testnet";
|
static public final String TESTNET = "testnet";
|
||||||
|
|
||||||
|
@Getter
|
||||||
private String name = null;
|
private String name = null;
|
||||||
|
@Getter
|
||||||
final private NetworkType networkType;
|
final private NetworkType networkType;
|
||||||
InetAddress hostAddress;
|
InetAddress hostAddress;
|
||||||
|
@Getter
|
||||||
private String host;
|
private String host;
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
int rpcPort = 0;
|
int rpcPort = 0;
|
||||||
private int levinPort = 0;
|
private int levinPort = 0;
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
private String username = "";
|
private String username = "";
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
private String password = "";
|
private String password = "";
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
private boolean favourite = false;
|
private boolean favourite = false;
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private boolean selected = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
@@ -193,7 +209,6 @@ public class Node {
|
|||||||
this.levinPort = socketAddress.getPort();
|
this.levinPort = socketAddress.getPort();
|
||||||
this.username = "";
|
this.username = "";
|
||||||
this.password = "";
|
this.password = "";
|
||||||
//this.name = socketAddress.getHostName(); // triggers DNS so we don't do it by default
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAddress() {
|
public String getAddress() {
|
||||||
@@ -204,14 +219,6 @@ public class Node {
|
|||||||
return hostAddress.getHostAddress();
|
return hostAddress.getHostAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getHost() {
|
|
||||||
return host;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getRpcPort() {
|
|
||||||
return rpcPort;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHost(String host) throws UnknownHostException {
|
public void setHost(String host) throws UnknownHostException {
|
||||||
if ((host == null) || (host.isEmpty()))
|
if ((host == null) || (host.isEmpty()))
|
||||||
throw new UnknownHostException("loopback not supported (yet?)");
|
throw new UnknownHostException("loopback not supported (yet?)");
|
||||||
@@ -219,18 +226,6 @@ public class Node {
|
|||||||
this.hostAddress = InetAddress.getByName(host);
|
this.hostAddress = InetAddress.getByName(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUsername(String user) {
|
|
||||||
username = user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPassword(String pass) {
|
|
||||||
password = pass;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRpcPort(int port) {
|
|
||||||
this.rpcPort = port;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName() {
|
public void setName() {
|
||||||
if (name == null)
|
if (name == null)
|
||||||
this.name = hostAddress.getHostName();
|
this.name = hostAddress.getHostName();
|
||||||
@@ -243,30 +238,6 @@ public class Node {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public NetworkType getNetworkType() {
|
|
||||||
return networkType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUsername() {
|
|
||||||
return username;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPassword() {
|
|
||||||
return password;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isFavourite() {
|
|
||||||
return favourite;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFavourite(boolean favourite) {
|
|
||||||
this.favourite = favourite;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void toggleFavourite() {
|
public void toggleFavourite() {
|
||||||
favourite = !favourite;
|
favourite = !favourite;
|
||||||
}
|
}
|
||||||
|
@@ -21,8 +21,8 @@ import com.burgstaller.okhttp.CachingAuthenticatorDecorator;
|
|||||||
import com.burgstaller.okhttp.digest.CachingAuthenticator;
|
import com.burgstaller.okhttp.digest.CachingAuthenticator;
|
||||||
import com.burgstaller.okhttp.digest.Credentials;
|
import com.burgstaller.okhttp.digest.Credentials;
|
||||||
import com.burgstaller.okhttp.digest.DigestAuthenticator;
|
import com.burgstaller.okhttp.digest.DigestAuthenticator;
|
||||||
import com.m2049r.levin.scanner.Dispatcher;
|
|
||||||
import com.m2049r.levin.scanner.LevinPeer;
|
import com.m2049r.levin.scanner.LevinPeer;
|
||||||
|
import com.m2049r.xmrwallet.util.NodePinger;
|
||||||
import com.m2049r.xmrwallet.util.OkHttpHelper;
|
import com.m2049r.xmrwallet.util.OkHttpHelper;
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
@@ -36,6 +36,8 @@ import java.util.Comparator;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
import okhttp3.HttpUrl;
|
import okhttp3.HttpUrl;
|
||||||
import okhttp3.MediaType;
|
import okhttp3.MediaType;
|
||||||
import okhttp3.OkHttpClient;
|
import okhttp3.OkHttpClient;
|
||||||
@@ -46,14 +48,24 @@ import okhttp3.ResponseBody;
|
|||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
public class NodeInfo extends Node {
|
public class NodeInfo extends Node {
|
||||||
final static public int MIN_MAJOR_VERSION = 11;
|
final static public int MIN_MAJOR_VERSION = 14;
|
||||||
final static public String RPC_VERSION = "2.0";
|
final static public String RPC_VERSION = "2.0";
|
||||||
|
|
||||||
|
@Getter
|
||||||
private long height = 0;
|
private long height = 0;
|
||||||
|
@Getter
|
||||||
private long timestamp = 0;
|
private long timestamp = 0;
|
||||||
|
@Getter
|
||||||
private int majorVersion = 0;
|
private int majorVersion = 0;
|
||||||
|
@Getter
|
||||||
private double responseTime = Double.MAX_VALUE;
|
private double responseTime = Double.MAX_VALUE;
|
||||||
|
@Getter
|
||||||
private int responseCode = 0;
|
private int responseCode = 0;
|
||||||
|
@Getter
|
||||||
|
private boolean tested = false;
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private boolean selecting = false;
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
height = 0;
|
height = 0;
|
||||||
@@ -61,13 +73,13 @@ public class NodeInfo extends Node {
|
|||||||
responseTime = Double.MAX_VALUE;
|
responseTime = Double.MAX_VALUE;
|
||||||
responseCode = 0;
|
responseCode = 0;
|
||||||
timestamp = 0;
|
timestamp = 0;
|
||||||
|
tested = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static public NodeInfo fromString(String nodeString) {
|
static public NodeInfo fromString(String nodeString) {
|
||||||
try {
|
try {
|
||||||
return new NodeInfo(nodeString);
|
return new NodeInfo(nodeString);
|
||||||
} catch (IllegalArgumentException ex) {
|
} catch (IllegalArgumentException ex) {
|
||||||
Timber.w(ex);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -113,26 +125,6 @@ public class NodeInfo extends Node {
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getHeight() {
|
|
||||||
return height;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getTimestamp() {
|
|
||||||
return timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMajorVersion() {
|
|
||||||
return majorVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getResponseTime() {
|
|
||||||
return responseTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getResponseCode() {
|
|
||||||
return responseCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSuccessful() {
|
public boolean isSuccessful() {
|
||||||
return (responseCode >= 200) && (responseCode < 300);
|
return (responseCode >= 200) && (responseCode < 300);
|
||||||
}
|
}
|
||||||
@@ -145,23 +137,20 @@ public class NodeInfo extends Node {
|
|||||||
return isSuccessful() && (majorVersion >= MIN_MAJOR_VERSION) && (responseTime < Double.MAX_VALUE);
|
return isSuccessful() && (majorVersion >= MIN_MAJOR_VERSION) && (responseTime < Double.MAX_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static public Comparator<NodeInfo> BestNodeComparator = new Comparator<NodeInfo>() {
|
static public Comparator<NodeInfo> BestNodeComparator = (o1, o2) -> {
|
||||||
@Override
|
if (o1.isValid()) {
|
||||||
public int compare(NodeInfo o1, NodeInfo o2) {
|
if (o2.isValid()) { // both are valid
|
||||||
if (o1.isValid()) {
|
// higher node wins
|
||||||
if (o2.isValid()) { // both are valid
|
int heightDiff = (int) (o2.height - o1.height);
|
||||||
// higher node wins
|
if (heightDiff != 0)
|
||||||
int heightDiff = (int) (o2.height - o1.height);
|
return heightDiff;
|
||||||
if (Math.abs(heightDiff) > Dispatcher.HEIGHT_WINDOW)
|
// if they are equal, faster node wins
|
||||||
return heightDiff;
|
return (int) Math.signum(o1.responseTime - o2.responseTime);
|
||||||
// if they are (nearly) equal, faster node wins
|
|
||||||
return (int) Math.signum(o1.responseTime - o2.responseTime);
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return 1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -192,7 +181,7 @@ public class NodeInfo extends Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static final int HTTP_TIMEOUT = OkHttpHelper.HTTP_TIMEOUT;
|
private static final int HTTP_TIMEOUT = OkHttpHelper.HTTP_TIMEOUT;
|
||||||
public static final double PING_GOOD = HTTP_TIMEOUT / 3; //ms
|
public static final double PING_GOOD = HTTP_TIMEOUT / 3.0; //ms
|
||||||
public static final double PING_MEDIUM = 2 * PING_GOOD; //ms
|
public static final double PING_MEDIUM = 2 * PING_GOOD; //ms
|
||||||
public static final double PING_BAD = HTTP_TIMEOUT;
|
public static final double PING_BAD = HTTP_TIMEOUT;
|
||||||
|
|
||||||
@@ -200,7 +189,15 @@ public class NodeInfo extends Node {
|
|||||||
return testRpcService(rpcPort);
|
return testRpcService(rpcPort);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean testRpcService(NodePinger.Listener listener) {
|
||||||
|
boolean result = testRpcService(rpcPort);
|
||||||
|
if (listener != null)
|
||||||
|
listener.publish(this);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean testRpcService(int port) {
|
private boolean testRpcService(int port) {
|
||||||
|
Timber.d("Testing %s", toNodeString());
|
||||||
clear();
|
clear();
|
||||||
try {
|
try {
|
||||||
OkHttpClient client = OkHttpHelper.getEagerClient();
|
OkHttpClient client = OkHttpHelper.getEagerClient();
|
||||||
@@ -247,8 +244,9 @@ public class NodeInfo extends Node {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException | JSONException ex) {
|
} catch (IOException | JSONException ex) {
|
||||||
// failure
|
Timber.d(ex);
|
||||||
Timber.d(ex.getMessage());
|
} finally {
|
||||||
|
tested = true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -20,6 +20,7 @@ import android.os.Parcel;
|
|||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.model.PendingTransaction;
|
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
|
// https://stackoverflow.com/questions/2139134/how-to-send-an-object-from-one-android-activity-to-another-using-intents
|
||||||
public class TxData implements Parcelable {
|
public class TxData implements Parcelable {
|
||||||
@@ -52,6 +53,10 @@ public class TxData implements Parcelable {
|
|||||||
return amount;
|
return amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double getAmountAsDouble() {
|
||||||
|
return 1.0 * amount / 1000000000000L;
|
||||||
|
}
|
||||||
|
|
||||||
public int getMixin() {
|
public int getMixin() {
|
||||||
return mixin;
|
return mixin;
|
||||||
}
|
}
|
||||||
@@ -68,6 +73,10 @@ public class TxData implements Parcelable {
|
|||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setAmount(double amount) {
|
||||||
|
this.amount = Wallet.getAmountFromDouble(amount);
|
||||||
|
}
|
||||||
|
|
||||||
public void setMixin(int mixin) {
|
public void setMixin(int mixin) {
|
||||||
this.mixin = mixin;
|
this.mixin = mixin;
|
||||||
}
|
}
|
||||||
|
@@ -18,11 +18,23 @@ package com.m2049r.xmrwallet.data;
|
|||||||
|
|
||||||
import android.os.Parcel;
|
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 btcAddress;
|
||||||
private String bip70;
|
@Getter
|
||||||
|
@Setter
|
||||||
private double btcAmount;
|
private double btcAmount;
|
||||||
|
|
||||||
public TxDataBtc() {
|
public TxDataBtc() {
|
||||||
@@ -33,44 +45,12 @@ public class TxDataBtc extends TxData {
|
|||||||
super(txDataBtc);
|
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
|
@Override
|
||||||
public void writeToParcel(Parcel out, int flags) {
|
public void writeToParcel(Parcel out, int flags) {
|
||||||
super.writeToParcel(out, flags);
|
super.writeToParcel(out, flags);
|
||||||
out.writeString(xmrtoUuid);
|
out.writeString(btcSymbol);
|
||||||
|
out.writeString(xmrtoOrderId);
|
||||||
out.writeString(btcAddress);
|
out.writeString(btcAddress);
|
||||||
out.writeString(bip70);
|
|
||||||
out.writeDouble(btcAmount);
|
out.writeDouble(btcAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,23 +67,35 @@ public class TxDataBtc extends TxData {
|
|||||||
|
|
||||||
protected TxDataBtc(Parcel in) {
|
protected TxDataBtc(Parcel in) {
|
||||||
super(in);
|
super(in);
|
||||||
xmrtoUuid = in.readString();
|
btcSymbol = in.readString();
|
||||||
|
xmrtoOrderId = in.readString();
|
||||||
btcAddress = in.readString();
|
btcAddress = in.readString();
|
||||||
bip70 = in.readString();
|
|
||||||
btcAmount = in.readDouble();
|
btcAmount = in.readDouble();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append(",xmrtoUuid:");
|
sb.append("xmrtoOrderId:");
|
||||||
sb.append(xmrtoUuid);
|
sb.append(xmrtoOrderId);
|
||||||
|
sb.append(",btcSymbol:");
|
||||||
|
sb.append(btcSymbol);
|
||||||
sb.append(",btcAddress:");
|
sb.append(",btcAddress:");
|
||||||
sb.append(btcAddress);
|
sb.append(btcAddress);
|
||||||
sb.append(",bip70:");
|
|
||||||
sb.append(bip70);
|
|
||||||
sb.append(",btcAmount:");
|
sb.append(",btcAmount:");
|
||||||
sb.append(btcAmount);
|
sb.append(btcAmount);
|
||||||
return sb.toString();
|
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;
|
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.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import timber.log.Timber;
|
|
||||||
|
|
||||||
public class UserNotes {
|
public class UserNotes {
|
||||||
public String txNotes = "";
|
public String txNotes = "";
|
||||||
public String note = "";
|
public String note = "";
|
||||||
|
public String xmrtoTag = null;
|
||||||
public String xmrtoKey = null;
|
public String xmrtoKey = null;
|
||||||
public String xmrtoAmount = null; // could be a double - but we are not doing any calculations
|
public String xmrtoAmount = null; // could be a double - but we are not doing any calculations
|
||||||
|
public String xmrtoCurrency = null;
|
||||||
public String xmrtoDestination = null;
|
public String xmrtoDestination = null;
|
||||||
|
|
||||||
public UserNotes(final String txNotes) {
|
public UserNotes(final String txNotes) {
|
||||||
@@ -35,13 +36,15 @@ public class UserNotes {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.txNotes = txNotes;
|
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);
|
Matcher m = p.matcher(txNotes);
|
||||||
if (m.find()) {
|
if (m.find()) {
|
||||||
xmrtoKey = m.group(1);
|
xmrtoTag = m.group(1);
|
||||||
xmrtoAmount = m.group(2);
|
xmrtoKey = m.group(2);
|
||||||
xmrtoDestination = m.group(3);
|
xmrtoAmount = m.group(3);
|
||||||
note = m.group(4);
|
xmrtoCurrency = m.group(4);
|
||||||
|
xmrtoDestination = m.group(5);
|
||||||
|
note = m.group(6);
|
||||||
} else {
|
} else {
|
||||||
note = txNotes;
|
note = txNotes;
|
||||||
}
|
}
|
||||||
@@ -56,12 +59,15 @@ public class UserNotes {
|
|||||||
txNotes = buildTxNote();
|
txNotes = buildTxNote();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setXmrtoStatus(QueryOrderStatus xmrtoStatus) {
|
public void setXmrtoOrder(CreateOrder order) {
|
||||||
if (xmrtoStatus != null) {
|
if (order != null) {
|
||||||
xmrtoKey = xmrtoStatus.getUuid();
|
xmrtoTag = order.TAG;
|
||||||
xmrtoAmount = String.valueOf(xmrtoStatus.getBtcAmount());
|
xmrtoKey = order.getOrderId();
|
||||||
xmrtoDestination = xmrtoStatus.getBtcDestAddress();
|
xmrtoAmount = Helper.getDisplayAmount(order.getBtcAmount());
|
||||||
|
xmrtoCurrency = order.getBtcCurrency();
|
||||||
|
xmrtoDestination = order.getBtcAddress();
|
||||||
} else {
|
} else {
|
||||||
|
xmrtoTag = null;
|
||||||
xmrtoKey = null;
|
xmrtoKey = null;
|
||||||
xmrtoAmount = null;
|
xmrtoAmount = null;
|
||||||
xmrtoDestination = null;
|
xmrtoDestination = null;
|
||||||
@@ -70,15 +76,18 @@ public class UserNotes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String buildTxNote() {
|
private String buildTxNote() {
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuilder sb = new StringBuilder();
|
||||||
if (xmrtoKey != null) {
|
if (xmrtoKey != null) {
|
||||||
if ((xmrtoAmount == null) || (xmrtoDestination == null))
|
if ((xmrtoAmount == null) || (xmrtoDestination == null))
|
||||||
throw new IllegalArgumentException("Broken notes");
|
throw new IllegalArgumentException("Broken notes");
|
||||||
sb.append("{");
|
sb.append("{");
|
||||||
|
sb.append(xmrtoTag);
|
||||||
|
sb.append("-");
|
||||||
sb.append(xmrtoKey);
|
sb.append(xmrtoKey);
|
||||||
sb.append(",");
|
sb.append(",");
|
||||||
sb.append(xmrtoAmount);
|
sb.append(xmrtoAmount);
|
||||||
sb.append("BTC,");
|
sb.append(xmrtoCurrency);
|
||||||
|
sb.append(",");
|
||||||
sb.append(xmrtoDestination);
|
sb.append(xmrtoDestination);
|
||||||
sb.append("}");
|
sb.append("}");
|
||||||
if ((note != null) && (!note.isEmpty()))
|
if ((note != null) && (!note.isEmpty()))
|
||||||
|
@@ -16,26 +16,25 @@
|
|||||||
|
|
||||||
package com.m2049r.xmrwallet.dialog;
|
package com.m2049r.xmrwallet.dialog;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
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 android.support.v4.app.DialogFragment;
|
import androidx.fragment.app.DialogFragment;
|
||||||
import android.support.v4.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import android.support.v4.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
import android.support.v4.app.FragmentTransaction;
|
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 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;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
@@ -63,15 +62,15 @@ public class AboutFragment extends DialogFragment {
|
|||||||
((TextView) view.findViewById(R.id.tvHelp)).setText(Html.fromHtml(getLicencesHtml()));
|
((TextView) view.findViewById(R.id.tvHelp)).setText(Html.fromHtml(getLicencesHtml()));
|
||||||
((TextView) view.findViewById(R.id.tvVersion)).setText(getString(R.string.about_version, BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE));
|
((TextView) view.findViewById(R.id.tvVersion)).setText(getString(R.string.about_version, BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE));
|
||||||
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getActivity())
|
||||||
builder.setView(view);
|
.setView(view)
|
||||||
builder.setNegativeButton(R.string.about_close,
|
.setNegativeButton(R.string.about_close,
|
||||||
new DialogInterface.OnClickListener() {
|
new DialogInterface.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return builder.create();
|
return builder.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -16,19 +16,20 @@
|
|||||||
|
|
||||||
package com.m2049r.xmrwallet.dialog;
|
package com.m2049r.xmrwallet.dialog;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
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 android.support.v4.app.DialogFragment;
|
|
||||||
import android.support.v4.app.Fragment;
|
|
||||||
import android.support.v4.app.FragmentManager;
|
|
||||||
import android.support.v4.app.FragmentTransaction;
|
|
||||||
import android.text.Html;
|
import android.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.m2049r.xmrwallet.R;
|
import com.m2049r.xmrwallet.R;
|
||||||
|
|
||||||
public class CreditsFragment extends DialogFragment {
|
public class CreditsFragment extends DialogFragment {
|
||||||
@@ -54,16 +55,15 @@ public class CreditsFragment extends DialogFragment {
|
|||||||
|
|
||||||
((TextView) view.findViewById(R.id.tvCredits)).setText(Html.fromHtml(getString(R.string.credits_text)));
|
((TextView) view.findViewById(R.id.tvCredits)).setText(Html.fromHtml(getString(R.string.credits_text)));
|
||||||
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getActivity())
|
||||||
builder.setView(view);
|
.setView(view)
|
||||||
builder.setNegativeButton(R.string.about_close,
|
.setNegativeButton(R.string.about_close,
|
||||||
new DialogInterface.OnClickListener() {
|
new DialogInterface.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return builder.create();
|
return builder.create();
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -16,19 +16,20 @@
|
|||||||
|
|
||||||
package com.m2049r.xmrwallet.dialog;
|
package com.m2049r.xmrwallet.dialog;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
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 android.support.v4.app.DialogFragment;
|
|
||||||
import android.support.v4.app.Fragment;
|
|
||||||
import android.support.v4.app.FragmentManager;
|
|
||||||
import android.support.v4.app.FragmentTransaction;
|
|
||||||
import android.text.Html;
|
import android.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.m2049r.xmrwallet.R;
|
import com.m2049r.xmrwallet.R;
|
||||||
|
|
||||||
public class HelpFragment extends DialogFragment {
|
public class HelpFragment extends DialogFragment {
|
||||||
@@ -65,15 +66,15 @@ public class HelpFragment extends DialogFragment {
|
|||||||
if (helpId > 0)
|
if (helpId > 0)
|
||||||
((TextView) view.findViewById(R.id.tvHelp)).setText(Html.fromHtml(getString(helpId)));
|
((TextView) view.findViewById(R.id.tvHelp)).setText(Html.fromHtml(getString(helpId)));
|
||||||
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getActivity())
|
||||||
builder.setView(view);
|
.setView(view)
|
||||||
builder.setNegativeButton(R.string.help_ok,
|
.setNegativeButton(R.string.help_ok,
|
||||||
new DialogInterface.OnClickListener() {
|
new DialogInterface.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return builder.create();
|
return builder.create();
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -16,19 +16,20 @@
|
|||||||
|
|
||||||
package com.m2049r.xmrwallet.dialog;
|
package com.m2049r.xmrwallet.dialog;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
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 android.support.v4.app.DialogFragment;
|
|
||||||
import android.support.v4.app.Fragment;
|
|
||||||
import android.support.v4.app.FragmentManager;
|
|
||||||
import android.support.v4.app.FragmentTransaction;
|
|
||||||
import android.text.Html;
|
import android.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.m2049r.xmrwallet.R;
|
import com.m2049r.xmrwallet.R;
|
||||||
|
|
||||||
public class PrivacyFragment extends DialogFragment {
|
public class PrivacyFragment extends DialogFragment {
|
||||||
@@ -54,15 +55,15 @@ public class PrivacyFragment extends DialogFragment {
|
|||||||
|
|
||||||
((TextView) view.findViewById(R.id.tvCredits)).setText(Html.fromHtml(getString(R.string.privacy_policy)));
|
((TextView) view.findViewById(R.id.tvCredits)).setText(Html.fromHtml(getString(R.string.privacy_policy)));
|
||||||
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getActivity())
|
||||||
builder.setView(view);
|
.setView(view)
|
||||||
builder.setNegativeButton(R.string.about_close,
|
.setNegativeButton(R.string.about_close,
|
||||||
new DialogInterface.OnClickListener() {
|
new DialogInterface.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return builder.create();
|
return builder.create();
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -17,7 +17,6 @@ package com.m2049r.xmrwallet.dialog;
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@@ -26,7 +25,8 @@ import android.view.WindowManager;
|
|||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.BuildConfig;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
|
||||||
import com.m2049r.xmrwallet.R;
|
import com.m2049r.xmrwallet.R;
|
||||||
import com.m2049r.xmrwallet.util.Helper;
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user