1
mirror of https://github.com/m2049r/xmrwallet synced 2025-11-15 05:07:36 +01:00

Compare commits

..

7 Commits

Author SHA1 Message Date
m2049r
0e187d3b20 version 2017-11-02 22:52:13 +01:00
m2049r
716b830b7b Tweaks based on alpha feedback (#110)
* donation+privacy policy screens + bugfixes

* opacity

* mnemonic left aligned

* smaller scan button

* spread out fabs

* doExchnage on lose focus of amount

* specify wallet create type
2017-11-02 22:48:20 +01:00
m2049r
4ac6a03d63 rename fresh wallet (no cachefile) (#109) 2017-11-02 11:46:03 +01:00
m2049r
7eb86ea618 tx details consistent with tx list (#107) 2017-11-01 20:33:58 +01:00
Stephan Hagios
4cfd166ed7 Adjusted visibility of fields and methods. (#102)
* Adjusted visibility of fields and methods.

* Adjusted visibility of fields and methods after rebase
2017-11-01 19:47:24 +01:00
m2049r
44f241f4ee fix progress dialog not showing (#106)
also, new version
2017-11-01 19:26:18 +01:00
m2049r
62b77fc987 no more animation because of OOMs (#105) 2017-11-01 10:56:47 +01:00
62 changed files with 641 additions and 298 deletions

1
.gitignore vendored
View File

@@ -7,3 +7,4 @@
/captures
.externalNativeBuild
.DS_Store
/app/release

View File

@@ -21,7 +21,6 @@ You may lose all your Moneroj if you use this App. Be cautious when spending on
- Monerujo means "Monero Wallet" according to https://www.reddit.com/r/Monero/comments/3exy7t/esperanto_corner/
### TODO
- review visibility of methods/classes
- more sensible error dialogs
### Issues / Pitfalls

View File

@@ -8,8 +8,8 @@ android {
applicationId "com.m2049r.xmrwallet"
minSdkVersion 21
targetSdkVersion 25
versionCode 29
versionName "1.1.2-alpha"
versionCode 31
versionName "1.1.3-alpha"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

View File

@@ -33,6 +33,7 @@ import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.TextView;
import com.m2049r.xmrwallet.layout.Toolbar;
import com.m2049r.xmrwallet.model.Wallet;
import com.m2049r.xmrwallet.model.WalletManager;
import com.m2049r.xmrwallet.util.Helper;
@@ -48,16 +49,16 @@ public class GenerateFragment extends Fragment {
static final String TYPE_SEED = "seed";
static final String TYPE_VIEWONLY = "view";
TextInputLayout etWalletName;
TextInputLayout etWalletPassword;
TextInputLayout etWalletAddress;
TextInputLayout etWalletMnemonic;
TextInputLayout etWalletViewKey;
TextInputLayout etWalletSpendKey;
TextInputLayout etWalletRestoreHeight;
Button bGenerate;
private TextInputLayout etWalletName;
private TextInputLayout etWalletPassword;
private TextInputLayout etWalletAddress;
private TextInputLayout etWalletMnemonic;
private TextInputLayout etWalletViewKey;
private TextInputLayout etWalletSpendKey;
private TextInputLayout etWalletRestoreHeight;
private Button bGenerate;
String type = null;
private String type = null;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
@@ -366,7 +367,25 @@ public class GenerateFragment extends Fragment {
public void onResume() {
super.onResume();
Log.d(TAG, "onResume()");
activityCallback.setTitle(getString(R.string.generate_title));
activityCallback.setTitle(getString(R.string.generate_title) + " - " + getType());
activityCallback.setToolbarButton(Toolbar.BUTTON_BACK);
}
String getType() {
switch (type) {
case TYPE_KEY:
return getString(R.string.generate_wallet_type_key);
case TYPE_NEW:
return getString(R.string.generate_wallet_type_new);
case TYPE_SEED:
return getString(R.string.generate_wallet_type_seed);
case TYPE_VIEWONLY:
return getString(R.string.generate_wallet_type_view);
default:
Log.e(TAG, "unknown type " + type);
return "?";
}
}
GenerateFragment.Listener activityCallback;
@@ -379,6 +398,9 @@ public class GenerateFragment extends Fragment {
void onGenerate(String name, String password, String address, String viewKey, String spendKey, long height);
void setTitle(String title);
void setToolbarButton(int type);
}
@Override

View File

@@ -47,8 +47,10 @@ import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.m2049r.xmrwallet.dialog.DonationFragment;
import com.m2049r.xmrwallet.dialog.HelpFragment;
import com.m2049r.xmrwallet.dialog.LicensesFragment;
import com.m2049r.xmrwallet.dialog.PrivacyFragment;
import com.m2049r.xmrwallet.layout.Toolbar;
import com.m2049r.xmrwallet.model.Wallet;
import com.m2049r.xmrwallet.model.WalletManager;
@@ -73,9 +75,8 @@ public class LoginActivity extends AppCompatActivity
private static final String GENERATE_STACK = "gen";
static final int DAEMON_TIMEOUT = 500; // deamon must respond in 500ms
static final int DAEMON_DNS_TIMEOUT = 5000; // how long to wait for DNS resolver
Toolbar toolbar;
private Toolbar toolbar;
@Override
public void setToolbarButton(int type) {
@@ -121,7 +122,8 @@ public class LoginActivity extends AppCompatActivity
finish();
break;
case Toolbar.BUTTON_DONATE:
Toast.makeText(LoginActivity.this, getString(R.string.label_donate), Toast.LENGTH_SHORT).show();
DonationFragment.display(getSupportFragmentManager());
break;
case Toolbar.BUTTON_NONE:
default:
Log.e(TAG, "Button " + type + "pressed - how can this be?");
@@ -251,7 +253,7 @@ public class LoginActivity extends AppCompatActivity
// copy + delete seems safer than rename because we call rollback easily
boolean renameWallet(File walletFile, String newName) {
if (copyWallet(walletFile, new File(walletFile.getParentFile(), newName), false)) {
if (copyWallet(walletFile, new File(walletFile.getParentFile(), newName), false, true)) {
deleteWallet(walletFile);
return true;
} else {
@@ -356,7 +358,7 @@ public class LoginActivity extends AppCompatActivity
// TODO probably better to copy to a new file and then rename
// then if something fails we have the old backup at least
// or just create a new backup every time and keep n old backups
boolean success = copyWallet(walletFile, backupFile, true);
boolean success = copyWallet(walletFile, backupFile, true, true);
Log.d(TAG, "copyWallet is " + success);
return success;
}
@@ -604,6 +606,8 @@ public class LoginActivity extends AppCompatActivity
if (progressDialog != null) progressDialog.show();
}
}, delay);
} else {
progressDialog.show();
}
}
@@ -969,8 +973,8 @@ public class LoginActivity extends AppCompatActivity
}
}
boolean copyWallet(File srcWallet, File dstWallet, boolean backupMode) {
if (walletExists(dstWallet, true) && !backupMode) return false;
boolean copyWallet(File srcWallet, File dstWallet, boolean overwrite, boolean ignoreCacheError) {
if (walletExists(dstWallet, true) && !overwrite) return false;
boolean success = false;
File srcDir = srcWallet.getParentFile();
String srcName = srcWallet.getName();
@@ -980,8 +984,8 @@ public class LoginActivity extends AppCompatActivity
try {
copyFile(new File(srcDir, srcName), new File(dstDir, dstName));
} catch (IOException ex) {
Log.d(TAG, "CACHE " + backupMode);
if (!backupMode) { // ignore cache backup error if backing up (can be resynced)
Log.d(TAG, "CACHE " + ignoreCacheError);
if (!ignoreCacheError) { // ignore cache backup error if backing up (can be resynced)
throw ex;
}
}
@@ -1055,9 +1059,12 @@ public class LoginActivity extends AppCompatActivity
case R.id.action_details_help:
HelpFragment.displayHelp(getSupportFragmentManager(), R.raw.help_details);
return true;
case R.id.action_lincense_info:
case R.id.action_license_info:
LicensesFragment.displayLicensesFragment(getSupportFragmentManager());
return true;
case R.id.action_privacy_policy:
PrivacyFragment.display(getSupportFragmentManager());
return true;
case R.id.action_testnet:
try {
LoginFragment loginFragment = (LoginFragment)

View File

@@ -18,9 +18,7 @@ package com.m2049r.xmrwallet;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
@@ -66,7 +64,6 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
List<WalletManager.WalletInfo> walletList = new ArrayList<>();
List<WalletManager.WalletInfo> displayedList = new ArrayList<>();
ImageView ivGuntherWallets;
EditText etDummy;
DropDownEditText etDaemonAddress;
ArrayAdapter<String> nodeAdapter;
@@ -134,8 +131,6 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
Log.d(TAG, "onCreateView");
View view = inflater.inflate(R.layout.fragment_login, container, false);
ivGuntherWallets = (ImageView) view.findViewById(R.id.ivGuntherWallets);
fabScreen = (FrameLayout) view.findViewById(R.id.fabScreen);
fab = (FloatingActionButton) view.findViewById(R.id.fab);
fabNew = (FloatingActionButton) view.findViewById(R.id.fabNew);
@@ -148,6 +143,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
fabKeyL = (RelativeLayout) view.findViewById(R.id.fabKeyL);
fabSeedL = (RelativeLayout) view.findViewById(R.id.fabSeedL);
fab_pulse = AnimationUtils.loadAnimation(getContext(), R.anim.fab_pulse);
fab_open_screen = AnimationUtils.loadAnimation(getContext(), R.anim.fab_open_screen);
fab_close_screen = AnimationUtils.loadAnimation(getContext(), R.anim.fab_close_screen);
fab_open = AnimationUtils.loadAnimation(getContext(), R.anim.fab_open);
@@ -213,25 +209,10 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
});
loadPrefs();
return view;
}
void showGunther() {
ivGuntherWallets.setImageResource(R.drawable.gunther_wallets);
final AnimationDrawable guntherWalletsAnim = (AnimationDrawable) ivGuntherWallets.getDrawable();
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
guntherWalletsAnim.start();
}
}, getResources().getInteger(R.integer.gunther_wallets_delay));
}
void normalGunther() {
ivGuntherWallets.setImageResource(R.drawable.gunther_wallets_00);
}
// Callbacks from WalletInfoAdapter
@Override
public void onInteraction(final View view, final WalletManager.WalletInfo infoItem) {
@@ -289,9 +270,9 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
adapter.setInfos(displayedList);
adapter.notifyDataSetChanged();
if (displayedList.isEmpty()) {
showGunther();
fab.startAnimation(fab_pulse);
} else {
normalGunther();
fab.clearAnimation();
}
}
@@ -407,6 +388,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
private FrameLayout fabScreen;
private RelativeLayout fabNewL, fabViewL, fabKeyL, fabSeedL;
private Animation fab_open, fab_close, rotate_forward, rotate_backward, fab_open_screen, fab_close_screen;
private Animation fab_pulse;
public boolean isFabOpen() {
return isFabOpen;

View File

@@ -59,15 +59,15 @@ import java.util.Map;
public class ReceiveFragment extends Fragment {
static final String TAG = "ReceiveFragment";
ProgressBar pbProgress;
TextView tvAddress;
TextInputLayout etPaymentId;
ExchangeView evAmount;
Button bPaymentId;
Button bGenerate;
ImageView qrCode;
EditText etDummy;
ImageButton bCopyAddress;
private ProgressBar pbProgress;
private TextView tvAddress;
private TextInputLayout etPaymentId;
private ExchangeView evAmount;
private Button bPaymentId;
private Button bGenerate;
private ImageView qrCode;
private EditText etDummy;
private ImageButton bCopyAddress;
//String name;

View File

@@ -34,7 +34,7 @@ import me.dm7.barcodescanner.zxing.ZXingScannerView;
public class ScannerFragment extends Fragment implements ZXingScannerView.ResultHandler {
static final String TAG = "ScannerFragment";
Listener activityCallback;
private Listener activityCallback;
public interface Listener {
boolean onAddressScanned(String uri);

View File

@@ -51,33 +51,30 @@ import com.m2049r.xmrwallet.util.TxData;
public class SendFragment extends Fragment {
static final String TAG = "SendFragment";
EditText etDummy;
private EditText etDummy;
ScrollView scrollview;
private ScrollView scrollview;
TextInputLayout etAddress;
TextInputLayout etPaymentId;
//TextInputLayout etAmount;
ExchangeView evAmount;
TextView tvAmountB;
Spinner sCurrencyA;
Spinner sCurrencyB;
private TextInputLayout etAddress;
private TextInputLayout etPaymentId;
Button bScan;
Spinner sMixin;
Spinner sPriority;
Button bPrepareSend;
Button bDispose;
Button bPaymentId;
LinearLayout llConfirmSend;
TextView tvTxAmount;
TextView tvTxFee;
private ExchangeView evAmount;
private Button bScan;
private Spinner sMixin;
private Spinner sPriority;
private Button bPrepareSend;
private Button bDispose;
private Button bPaymentId;
private LinearLayout llConfirmSend;
private TextView tvTxAmount;
private TextView tvTxFee;
//TextView tvTxDust;
TextView tvTxTotal;
EditText etNotes;
Button bSend;
Button bReallySend;
ProgressBar pbProgress;
private TextView tvTxTotal;
private EditText etNotes;
private Button bSend;
private Button bReallySend;
private ProgressBar pbProgress;
final static int Mixins[] = {4, 7, 12, 25}; // must match the layout XML
final static PendingTransaction.Priority Priorities[] =
@@ -102,9 +99,6 @@ public class SendFragment extends Fragment {
etAddress = (TextInputLayout) view.findViewById(R.id.etAddress);
etPaymentId = (TextInputLayout) view.findViewById(R.id.etPaymentId);
evAmount = (ExchangeView) view.findViewById(R.id.evAmount);
tvAmountB = (TextView) view.findViewById(R.id.tvAmountB);
sCurrencyA = (Spinner) view.findViewById(R.id.sCurrencyA);
sCurrencyB = (Spinner) view.findViewById(R.id.sCurrencyB);
bScan = (Button) view.findViewById(R.id.bScan);
bPrepareSend = (Button) view.findViewById(R.id.bPrepareSend);
@@ -140,18 +134,6 @@ public class SendFragment extends Fragment {
}
});
evAmount.setOnNewAmountListener(new ExchangeView.OnNewAmountListener() {
@Override
public void onNewAmount(String xmr) {
if ((xmr != null)) {
// stupid workaround to not show error on open of screen
if ((checkAddressNoError() && checkAmountWithError()) || checkAmount()) {
etPaymentId.requestFocus();
}
}
}
});
etPaymentId.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() {
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) || (actionId == EditorInfo.IME_ACTION_DONE)) {
@@ -406,9 +388,6 @@ public class SendFragment extends Fragment {
}
if ((data != null) && (data.amount <= 0)) {
evAmount.focus();
} else {
etDummy.requestFocus();
Helper.hideKeyboard(getActivity());
}
}

View File

@@ -57,17 +57,17 @@ public class TxFragment extends Fragment {
TS_FORMATTER.setTimeZone(tz);
}
TextView tvTxTimestamp;
TextView tvTxId;
TextView tvTxKey;
TextView tvDestination;
TextView tvTxPaymentId;
TextView tvTxBlockheight;
TextView tvTxAmount;
TextView tvTxFee;
TextView tvTxTransfers;
TextView etTxNotes;
Button bTxNotes;
private TextView tvTxTimestamp;
private TextView tvTxId;
private TextView tvTxKey;
private TextView tvDestination;
private TextView tvTxPaymentId;
private TextView tvTxBlockheight;
private TextView tvTxAmount;
private TextView tvTxFee;
private TextView tvTxTransfers;
private TextView etTxNotes;
private Button bTxNotes;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
@@ -212,18 +212,20 @@ public class TxFragment extends Fragment {
}
String sign = (info.direction == TransactionInfo.Direction.Direction_In ? "+" : "-");
tvTxAmount.setText(sign + Wallet.getDisplayAmount(info.amount));
long realAmount = info.amount;
if (info.isPending) {
realAmount = realAmount - info.fee;
}
tvTxAmount.setText(sign + Wallet.getDisplayAmount(realAmount));
if ((info.fee > 0)) {
String fee = Wallet.getDisplayAmount(info.fee);
if (info.isPending) {
tvTxFee.setText(getString(R.string.tx_list_fee_pending, fee));
} else {
tvTxFee.setText(getString(R.string.tx_list_fee, fee));
}
tvTxFee.setText(getString(R.string.tx_list_fee, fee));
} else {
tvTxFee.setText(null);
tvTxFee.setVisibility(View.GONE);
}
if (info.isFailed) {
tvTxAmount.setText(getString(R.string.tx_list_amount_failed, Wallet.getDisplayAmount(info.amount)));
tvTxFee.setText(getString(R.string.tx_list_failed_text));

View File

@@ -36,6 +36,7 @@ import android.util.Log;
import android.view.MenuItem;
import android.widget.Toast;
import com.m2049r.xmrwallet.dialog.DonationFragment;
import com.m2049r.xmrwallet.layout.Toolbar;
import com.m2049r.xmrwallet.model.PendingTransaction;
import com.m2049r.xmrwallet.model.TransactionInfo;
@@ -60,7 +61,7 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
public static final String REQUEST_ID = "id";
public static final String REQUEST_PW = "pw";
Toolbar toolbar;
private Toolbar toolbar;
@Override
public void setToolbarButton(int type) {
@@ -154,7 +155,7 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
onWalletDetails();
return true;
case R.id.action_donate:
onWalletDetails();
DonationFragment.display(getSupportFragmentManager());
return true;
case R.id.action_share:
onShareTxInfo();

View File

@@ -53,16 +53,16 @@ public class WalletFragment extends Fragment
private TransactionInfoAdapter adapter;
private NumberFormat formatter = NumberFormat.getInstance();
FrameLayout flExchange;
TextView tvBalance;
TextView tvUnconfirmedAmount;
TextView tvProgress;
ImageView ivSynced;
ProgressBar pbProgress;
Button bReceive;
Button bSend;
private FrameLayout flExchange;
private TextView tvBalance;
private TextView tvUnconfirmedAmount;
private TextView tvProgress;
private ImageView ivSynced;
private ProgressBar pbProgress;
private Button bReceive;
private Button bSend;
Spinner sCurrency;
private Spinner sCurrency;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
@@ -305,17 +305,17 @@ public class WalletFragment extends Fragment
long daemonHeight = activityCallback.getDaemonHeight();
if (!wallet.isSynchronized()) {
long n = daemonHeight - wallet.getBlockChainHeight();
sync = formatter.format(n) + " " + getString(R.string.status_remaining);
sync = getString(R.string.status_syncing) + " " + formatter.format(n) + " " + getString(R.string.status_remaining);
if (firstBlock == 0) {
firstBlock = wallet.getBlockChainHeight();
}
int x = 100 - Math.round(100f * n / (1f * daemonHeight - firstBlock));
onProgress(getString(R.string.status_syncing) + " " + sync);
//onProgress(getString(R.string.status_syncing) + " " + sync);
if (x == 0) x = -1;
onProgress(x);
ivSynced.setVisibility(View.GONE);
} else {
sync = getString(R.string.status_synced) + ": " + formatter.format(wallet.getBlockChainHeight());
sync = getString(R.string.status_synced) + formatter.format(wallet.getBlockChainHeight());
ivSynced.setVisibility(View.VISIBLE);
}
}

View File

@@ -0,0 +1,114 @@
/*
* Copyright (c) 2017 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.
*/
/**
* Based on work by Adam Speakman http://speakman.net.nz
*/
package com.m2049r.xmrwallet.dialog;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.AsyncTask;
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.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.webkit.WebView;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.m2049r.xmrwallet.BuildConfig;
import com.m2049r.xmrwallet.R;
import com.m2049r.xmrwallet.util.Helper;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class DonationFragment extends DialogFragment {
static final String TAG = "DonationFragment";
private static final String FRAGMENT_TAG = "com.m2049r.xmrwalelt.dialog.DonationFragment";
/**
* Creates a new instance of LicensesFragment with no Close button.
*
* @return A new licenses fragment.
*/
public static DonationFragment newInstance() {
return new DonationFragment();
}
/**
* Builds and displays a licenses fragment with no Close button. Requires
* "/res/raw/licenses.html" and "/res/layout/licenses_fragment.xml" to be
* present.
*
* @param fm A fragment manager instance used to display this LicensesFragment.
*/
public static void display(FragmentManager fm) {
FragmentTransaction ft = fm.beginTransaction();
Fragment prev = fm.findFragmentByTag(FRAGMENT_TAG);
if (prev != null) {
ft.remove(prev);
}
ft.addToBackStack(null);
// Create and show the dialog.
DialogFragment newFragment = DonationFragment.newInstance();
newFragment.show(ft, FRAGMENT_TAG);
}
@SuppressLint("InflateParams")
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_donation, null);
((TextView) view.findViewById(R.id.tvCredits)).setText(Html.fromHtml(getString(R.string.donation_credits)));
((ImageButton) view.findViewById(R.id.bCopyAddress)).
setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Helper.clipBoardCopy(getActivity(), getString(R.string.label_copy_address),
((TextView) view.findViewById(R.id.tvWalletAddress)).getText().toString());
Toast.makeText(getActivity(), getString(R.string.message_copy_address), Toast.LENGTH_SHORT).show();
}
});
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(view);
builder.setNegativeButton(R.string.about_close,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
return builder.create();
}
}

View File

@@ -0,0 +1,93 @@
/*
* Copyright (c) 2017 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.
*/
/**
* Based on work by Adam Speakman http://speakman.net.nz
*/
package com.m2049r.xmrwallet.dialog;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import com.m2049r.xmrwallet.R;
import com.m2049r.xmrwallet.util.Helper;
public class PrivacyFragment extends DialogFragment {
static final String TAG = "PrivacyFragment";
private static final String FRAGMENT_TAG = "com.m2049r.xmrwalelt.dialog.PrivacyFragment";
/**
* Creates a new instance of LicensesFragment with no Close button.
*
* @return A new licenses fragment.
*/
public static PrivacyFragment newInstance() {
return new PrivacyFragment();
}
/**
* Builds and displays a licenses fragment with no Close button. Requires
* "/res/raw/licenses.html" and "/res/layout/licenses_fragment.xml" to be
* present.
*
* @param fm A fragment manager instance used to display this LicensesFragment.
*/
public static void display(FragmentManager fm) {
FragmentTransaction ft = fm.beginTransaction();
Fragment prev = fm.findFragmentByTag(FRAGMENT_TAG);
if (prev != null) {
ft.remove(prev);
}
ft.addToBackStack(null);
// Create and show the dialog.
DialogFragment newFragment = PrivacyFragment.newInstance();
newFragment.show(ft, FRAGMENT_TAG);
}
@SuppressLint("InflateParams")
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_privacy_policy, null);
((TextView) view.findViewById(R.id.tvCredits)).setText(Html.fromHtml(getString(R.string.privacy_policy)));
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(view);
builder.setNegativeButton(R.string.about_close,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
return builder.create();
}
}

View File

@@ -67,6 +67,7 @@ public class ExchangeView extends LinearLayout implements AsyncExchangeRate.List
public void setAmount(String xmrAmount) {
if (xmrAmount != null) {
setCurrencyA(0);
etAmount.getEditText().setText(xmrAmount);
setXmr(xmrAmount);
this.notXmrAmount = null;
doExchange();
@@ -191,6 +192,15 @@ public class ExchangeView extends LinearLayout implements AsyncExchangeRate.List
}
});
etAmount.getEditText().setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
doExchange();
}
}
});
etAmount.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() {
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) || (actionId == EditorInfo.IME_ACTION_DONE)) {

View File

@@ -47,10 +47,10 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
//static final int TX_PENDING = Color.rgb(72, 53, 176);
//static final int TX_FAILED = Color.rgb(208, 0, 255);
int outboundColour;
int inboundColour;
int pendingColour;
int failedColour;
private int outboundColour;
private int inboundColour;
private int pendingColour;
private int failedColour;
public interface OnInteractionListener {
void onInteraction(View view, TransactionInfo item);
@@ -59,7 +59,7 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
private final List<TransactionInfo> infoItems;
private final OnInteractionListener listener;
Context context;
private Context context;
public TransactionInfoAdapter(Context context, OnInteractionListener listener) {
this.context = context;

View File

@@ -31,9 +31,9 @@ import android.os.Process;
public class MoneroHandlerThread extends Thread {
// from src/cryptonote_config.h
static public final long THREAD_STACK_SIZE = 5 * 1024 * 1024;
int mPriority;
int mTid = -1;
Looper mLooper;
private int mPriority;
private int mTid = -1;
private Looper mLooper;
public MoneroHandlerThread(String name) {
super(null, null, name, THREAD_STACK_SIZE);
@@ -47,7 +47,7 @@ public class MoneroHandlerThread extends Thread {
* @param priority The priority to run the thread at. The value supplied must be from
* {@link android.os.Process} and not from java.lang.Thread.
*/
public MoneroHandlerThread(String name, int priority) {
MoneroHandlerThread(String name, int priority) {
super(null, null, name, THREAD_STACK_SIZE);
mPriority = priority;
}
@@ -57,7 +57,7 @@ public class MoneroHandlerThread extends Thread {
* setup before Looper loops.
*/
protected void onLooperPrepared() {
private void onLooperPrepared() {
}
@Override
@@ -81,7 +81,7 @@ public class MoneroHandlerThread extends Thread {
*
* @return The looper.
*/
public Looper getLooper() {
Looper getLooper() {
if (!isAlive()) {
return null;
}

View File

@@ -254,7 +254,6 @@ public class WalletService extends Service {
/////////////////////////////////////////////
/////////////////////////////////////////////
private Looper mServiceLooper;
private WalletService.ServiceHandler mServiceHandler;
private boolean errorState = false;
@@ -398,8 +397,8 @@ public class WalletService extends Service {
thread.start();
// Get the HandlerThread's Looper and use it for our Handler
mServiceLooper = thread.getLooper();
mServiceHandler = new WalletService.ServiceHandler(mServiceLooper);
final Looper serviceLooper = thread.getLooper();
mServiceHandler = new WalletService.ServiceHandler(serviceLooper);
Log.d(TAG, "Service created");
}

View File

@@ -24,19 +24,19 @@ import org.json.JSONException;
import org.json.JSONObject;
public class AsyncExchangeRate extends AsyncTask<String, Void, Boolean> {
static final String TAG = "AsyncGetExchangeRate";
private static final String TAG = "AsyncGetExchangeRate";
static final long TIME_REFRESH_INTERVAL = 60000; // refresh exchange rate max every minute
private static final long TIME_REFRESH_INTERVAL = 60000; // refresh exchange rate max every minute
static protected long RateTime = 0;
static protected double Rate = 0;
static protected String Fiat = null;
private static long RateTime = 0;
private static double Rate = 0;
private static String Fiat = null;
public interface Listener {
void exchange(String currencyA, String currencyB, double rate);
}
Listener listener;
private Listener listener;
public AsyncExchangeRate(Listener listener) {
super();
@@ -49,9 +49,9 @@ public class AsyncExchangeRate extends AsyncTask<String, Void, Boolean> {
super.onPreExecute();
}
boolean inverse = false;
String currencyA = null;
String currencyB = null;
private boolean inverse = false;
private String currencyA = null;
private String currencyB = null;
@Override
protected Boolean doInBackground(String... params) {
@@ -125,7 +125,7 @@ public class AsyncExchangeRate extends AsyncTask<String, Void, Boolean> {
}
}
String getExchangeRate(String fiat) {
private String getExchangeRate(String fiat) {
String jsonResponse =
Helper.getUrl("https://api.kraken.com/0/public/Ticker?pair=XMR" + fiat);
if (jsonResponse == null) return null;

View File

@@ -118,7 +118,7 @@ public class Helper {
}
/* Checks if external storage is available for read and write */
static public boolean isExternalStorageWritable() {
private static boolean isExternalStorageWritable() {
String state = Environment.getExternalStorageState();
return Environment.MEDIA_MOUNTED.equals(state);
}
@@ -156,7 +156,7 @@ public class Helper {
}
// amountString must have '.' as decimal point
static public String getDisplayAmount(String amountString, int maxDecimals) {
private static String getDisplayAmount(String amountString, int maxDecimals) {
int lastZero = 0;
int decimal = 0;
for (int i = amountString.length() - 1; i >= 0; i--) {

View File

@@ -22,9 +22,9 @@ import java.util.List;
public class NodeList {
static private final String TAG = "NodeList";
static public final int MAX_SIZE = 5;
private static final int MAX_SIZE = 5;
List<String> nodes = new ArrayList<>();
private List<String> nodes = new ArrayList<>();
public List<String> getNodes() {
return nodes;

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<scale
android:duration="500"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:interpolator="@android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
android:repeatMode="reverse"
android:toXScale="2.0"
android:toYScale="2.0" />
</set>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -1,73 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<item
android:drawable="@drawable/gunther_wallets_00"
android:duration="500" />
<item
android:drawable="@drawable/gunther_wallets_01"
android:duration="200" />
<item
android:drawable="@drawable/gunther_wallets_02"
android:duration="2000" />
<item
android:drawable="@drawable/gunther_wallets_03"
android:duration="1000" />
<item
android:drawable="@drawable/gunther_wallets_04"
android:duration="100" />
<item
android:drawable="@drawable/gunther_wallets_05"
android:duration="1000" />
<item
android:drawable="@drawable/gunther_wallets_06"
android:duration="0" />
<item
android:drawable="@drawable/gunther_wallets_07"
android:duration="0" />
<item
android:drawable="@drawable/gunther_wallets_08"
android:duration="0" />
<item
android:drawable="@drawable/gunther_wallets_09"
android:duration="0" />
<item
android:drawable="@drawable/gunther_wallets_10"
android:duration="0" />
<item
android:drawable="@drawable/gunther_wallets_11"
android:duration="0" />
<item
android:drawable="@drawable/gunther_wallets_12"
android:duration="0" />
<item
android:drawable="@drawable/gunther_wallets_13"
android:duration="0" />
<item
android:drawable="@drawable/gunther_wallets_14"
android:duration="0" />
<item
android:drawable="@drawable/gunther_wallets_15"
android:duration="0" />
<item
android:drawable="@drawable/gunther_wallets_16"
android:duration="0" />
<item
android:drawable="@drawable/gunther_wallets_17"
android:duration="0" />
<item
android:drawable="@drawable/gunther_wallets_18"
android:duration="5000" />
<item
android:drawable="@drawable/gunther_wallets_19"
android:duration="0" />
<item
android:drawable="@drawable/gunther_wallets_20"
android:duration="0" />
<item
android:drawable="@drawable/gunther_wallets_21"
android:duration="100" />
<item
android:drawable="@drawable/gunther_wallets_22"
android:duration="200" />
</animation-list>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

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