mirror of
https://github.com/m2049r/xmrwallet
synced 2025-09-03 08:23:04 +02:00
Compare commits
15 Commits
v1.1.3-alp
...
v1.2.4
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1875e2df62 | ||
![]() |
347123d961 | ||
![]() |
f5ad07c2b0 | ||
![]() |
62695af9c6 | ||
![]() |
3b1c3d564b | ||
![]() |
b28a140b48 | ||
![]() |
75bba4a091 | ||
![]() |
cfb3c23003 | ||
![]() |
2cb87bab8e | ||
![]() |
1ddc3d6b58 | ||
![]() |
2fa48d7441 | ||
![]() |
545367db90 | ||
![]() |
d67e02cbcb | ||
![]() |
d3beb7ca3f | ||
![]() |
f951e1a621 |
@@ -8,8 +8,8 @@ android {
|
||||
applicationId "com.m2049r.xmrwallet"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 25
|
||||
versionCode 31
|
||||
versionName "1.1.3-alpha"
|
||||
versionCode 45
|
||||
versionName "1.2.4"
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
|
@@ -422,7 +422,21 @@ public class GenerateFragment extends Fragment {
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
inflater.inflate(R.menu.create_wallet_menu, menu);
|
||||
switch (type) {
|
||||
case TYPE_KEY:
|
||||
inflater.inflate(R.menu.create_wallet_keys, menu);
|
||||
break;
|
||||
case TYPE_NEW:
|
||||
inflater.inflate(R.menu.create_wallet_new, menu);
|
||||
break;
|
||||
case TYPE_SEED:
|
||||
inflater.inflate(R.menu.create_wallet_seed, menu);
|
||||
break;
|
||||
case TYPE_VIEWONLY:
|
||||
inflater.inflate(R.menu.create_wallet_view, menu);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
}
|
||||
}
|
||||
|
@@ -103,18 +103,6 @@ public class GenerateReviewFragment extends Fragment {
|
||||
copyAddress();
|
||||
}
|
||||
});
|
||||
view.findViewById(R.id.bCopySeed).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
nocopy();
|
||||
}
|
||||
});
|
||||
view.findViewById(R.id.bCopySepndKey).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
nocopy();
|
||||
}
|
||||
});
|
||||
view.findViewById(R.id.bAdvancedInfo).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
@@ -305,5 +293,6 @@ public class GenerateReviewFragment extends Fragment {
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
inflater.inflate(R.menu.wallet_details_menu, menu);
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
}
|
||||
}
|
@@ -47,9 +47,9 @@ import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.m2049r.xmrwallet.dialog.AboutFragment;
|
||||
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;
|
||||
@@ -132,7 +132,7 @@ public class LoginActivity extends AppCompatActivity
|
||||
});
|
||||
|
||||
if (Helper.getWritePermission(this)) {
|
||||
startLoginFragment();
|
||||
if (savedInstanceState == null) startLoginFragment();
|
||||
} else {
|
||||
Log.i(TAG, "Waiting for permissions");
|
||||
}
|
||||
@@ -1053,14 +1053,26 @@ public class LoginActivity extends AppCompatActivity
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_create_help:
|
||||
HelpFragment.displayHelp(getSupportFragmentManager(), R.raw.help_create);
|
||||
case R.id.action_create_help_new:
|
||||
HelpFragment.display(getSupportFragmentManager(), R.string.help_create_new);
|
||||
return true;
|
||||
case R.id.action_create_help_keys:
|
||||
HelpFragment.display(getSupportFragmentManager(), R.string.help_create_keys);
|
||||
return true;
|
||||
case R.id.action_create_help_view:
|
||||
HelpFragment.display(getSupportFragmentManager(), R.string.help_create_view);
|
||||
return true;
|
||||
case R.id.action_create_help_seed:
|
||||
HelpFragment.display(getSupportFragmentManager(), R.string.help_create_seed);
|
||||
return true;
|
||||
case R.id.action_details_help:
|
||||
HelpFragment.displayHelp(getSupportFragmentManager(), R.raw.help_details);
|
||||
HelpFragment.display(getSupportFragmentManager(), R.string.help_details);
|
||||
return true;
|
||||
case R.id.action_license_info:
|
||||
LicensesFragment.displayLicensesFragment(getSupportFragmentManager());
|
||||
AboutFragment.display(getSupportFragmentManager());
|
||||
return true;
|
||||
case R.id.action_help_list:
|
||||
HelpFragment.display(getSupportFragmentManager(), R.string.help_list);
|
||||
return true;
|
||||
case R.id.action_privacy_policy:
|
||||
PrivacyFragment.display(getSupportFragmentManager());
|
||||
@@ -1133,7 +1145,11 @@ public class LoginActivity extends AppCompatActivity
|
||||
}
|
||||
}
|
||||
|
||||
private class AsyncOpenWallet extends AsyncTask<WalletNode, Void, Boolean> {
|
||||
private class AsyncOpenWallet extends AsyncTask<WalletNode, Void, Integer> {
|
||||
final static int OK = 0;
|
||||
final static int TIMEOUT = 1;
|
||||
final static int INVALID = 2;
|
||||
final static int IOEX = 3;
|
||||
|
||||
WalletNode walletNode;
|
||||
|
||||
@@ -1144,45 +1160,57 @@ public class LoginActivity extends AppCompatActivity
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(WalletNode... params) {
|
||||
if (params.length != 1) return false;
|
||||
protected Integer doInBackground(WalletNode... params) {
|
||||
if (params.length != 1) return INVALID;
|
||||
this.walletNode = params[0];
|
||||
if (!walletNode.isValid()) return false;
|
||||
if (!walletNode.isValid()) return INVALID;
|
||||
|
||||
Log.d(TAG, "checking " + walletNode.getAddress());
|
||||
|
||||
long timeDA = new Date().getTime();
|
||||
SocketAddress address = new InetSocketAddress(walletNode.host, walletNode.port);
|
||||
long timeDB = new Date().getTime();
|
||||
Log.d(TAG, "Resolving " + walletNode.host + " took " + (timeDB - timeDA) + "ms.");
|
||||
Socket socket = new Socket();
|
||||
long timeA = new Date().getTime();
|
||||
try {
|
||||
long timeDA = new Date().getTime();
|
||||
SocketAddress address = new InetSocketAddress(walletNode.host, walletNode.port);
|
||||
long timeDB = new Date().getTime();
|
||||
Log.d(TAG, "Resolving " + walletNode.host + " took " + (timeDB - timeDA) + "ms.");
|
||||
Socket socket = new Socket();
|
||||
long timeA = new Date().getTime();
|
||||
socket.connect(address, LoginActivity.DAEMON_TIMEOUT);
|
||||
socket.close();
|
||||
long timeB = new Date().getTime();
|
||||
long time = timeB - timeA;
|
||||
Log.d(TAG, "Daemon " + walletNode.host + " is " + time + "ms away.");
|
||||
return (time < LoginActivity.DAEMON_TIMEOUT ? OK : TIMEOUT);
|
||||
} catch (IOException ex) {
|
||||
Log.d(TAG, "Cannot reach daemon " + walletNode.host + "/" + walletNode.port + " because " + ex.getMessage());
|
||||
return false;
|
||||
return IOEX;
|
||||
} catch (IllegalArgumentException ex) {
|
||||
Log.d(TAG, "Cannot reach daemon " + walletNode.host + "/" + walletNode.port + " because " + ex.getMessage());
|
||||
return INVALID;
|
||||
}
|
||||
long timeB = new Date().getTime();
|
||||
long time = timeB - timeA;
|
||||
Log.d(TAG, "Daemon " + walletNode.host + " is " + time + "ms away.");
|
||||
return time < LoginActivity.DAEMON_TIMEOUT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result) {
|
||||
protected void onPostExecute(Integer result) {
|
||||
super.onPostExecute(result);
|
||||
if (isDestroyed()) {
|
||||
return;
|
||||
}
|
||||
dismissProgressDialog();
|
||||
if (result) {
|
||||
Log.d(TAG, "selected wallet is ." + walletNode.name + ".");
|
||||
// now it's getting real, check if wallet exists
|
||||
promptAndStart(walletNode);
|
||||
} else {
|
||||
Toast.makeText(LoginActivity.this, getString(R.string.status_wallet_connect_timeout), Toast.LENGTH_LONG).show();
|
||||
switch (result) {
|
||||
case OK:
|
||||
Log.d(TAG, "selected wallet is ." + walletNode.name + ".");
|
||||
// now it's getting real, check if wallet exists
|
||||
promptAndStart(walletNode);
|
||||
break;
|
||||
case TIMEOUT:
|
||||
Toast.makeText(LoginActivity.this, getString(R.string.status_wallet_connect_timeout), Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
case INVALID:
|
||||
Toast.makeText(LoginActivity.this, getString(R.string.status_wallet_node_invalid), Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
case IOEX:
|
||||
Toast.makeText(LoginActivity.this, getString(R.string.status_wallet_connect_ioex), Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -65,6 +65,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||
List<WalletManager.WalletInfo> displayedList = new ArrayList<>();
|
||||
|
||||
EditText etDummy;
|
||||
ImageView ivGunther;
|
||||
DropDownEditText etDaemonAddress;
|
||||
ArrayAdapter<String> nodeAdapter;
|
||||
|
||||
@@ -131,6 +132,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||
Log.d(TAG, "onCreateView");
|
||||
View view = inflater.inflate(R.layout.fragment_login, container, false);
|
||||
|
||||
ivGunther = (ImageView) view.findViewById(R.id.ivGunther);
|
||||
fabScreen = (FrameLayout) view.findViewById(R.id.fabScreen);
|
||||
fab = (FloatingActionButton) view.findViewById(R.id.fab);
|
||||
fabNew = (FloatingActionButton) view.findViewById(R.id.fabNew);
|
||||
@@ -269,10 +271,18 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||
filterList();
|
||||
adapter.setInfos(displayedList);
|
||||
adapter.notifyDataSetChanged();
|
||||
|
||||
// deal with Gunther & FAB animation
|
||||
if (displayedList.isEmpty()) {
|
||||
fab.startAnimation(fab_pulse);
|
||||
if (ivGunther.getDrawable() == null) {
|
||||
ivGunther.setImageResource(R.drawable.gunther_desaturated);
|
||||
}
|
||||
} else {
|
||||
fab.clearAnimation();
|
||||
if (ivGunther.getDrawable() != null) {
|
||||
ivGunther.setImageDrawable(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,7 +339,10 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||
//private static final String PREF_TESTNET = "testnet";
|
||||
|
||||
private static final String PREF_DAEMONLIST_MAINNET =
|
||||
"node.moneroworld.com:18089;node.xmrbackb.one:18081;node.xmr.be:18081";
|
||||
"node.moneroworld.com:18089;node.xmrbackb.one;node.xmr.be";
|
||||
|
||||
private static final String PREF_DAEMONLIST_TESTNET =
|
||||
"testnet.xmrchain.net";
|
||||
|
||||
private NodeList daemonTestNet;
|
||||
private NodeList daemonMainNet;
|
||||
@@ -338,7 +351,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
|
||||
SharedPreferences sharedPref = activityCallback.getPrefs();
|
||||
|
||||
daemonMainNet = new NodeList(sharedPref.getString(PREF_DAEMON_MAINNET, PREF_DAEMONLIST_MAINNET));
|
||||
daemonTestNet = new NodeList(sharedPref.getString(PREF_DAEMON_TESTNET, ""));
|
||||
daemonTestNet = new NodeList(sharedPref.getString(PREF_DAEMON_TESTNET, PREF_DAEMONLIST_TESTNET));
|
||||
setNet(isTestnet(), false);
|
||||
}
|
||||
|
||||
|
@@ -112,21 +112,17 @@ public class ReceiveFragment extends Fragment {
|
||||
generateQr();
|
||||
}
|
||||
});
|
||||
/*
|
||||
evAmount.setOnAmountInvalidatedListener(new ExchangeView.OnAmountInvalidatedListener() {
|
||||
@Override
|
||||
public void onAmountInvalidated() {
|
||||
clearQR();
|
||||
}
|
||||
});
|
||||
|
||||
evAmount.setOnFailedExchangeListener(new ExchangeView.OnFailedExchangeListener() {
|
||||
@Override
|
||||
public void onFailedExchange() {
|
||||
Toast.makeText(getActivity(), getString(R.string.message_exchange_failed), Toast.LENGTH_LONG).show();
|
||||
if (isAdded()) {
|
||||
clearQR();
|
||||
Toast.makeText(getActivity(), getString(R.string.message_exchange_failed), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
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)) {
|
||||
@@ -373,7 +369,7 @@ public class ReceiveFragment extends Fragment {
|
||||
|
||||
private Bitmap getMoneroLogo() {
|
||||
if (logo == null) {
|
||||
logo = Helper.getBitmap(getContext(), R.drawable.ic_monero_qr);
|
||||
logo = Helper.getBitmap(getContext(), R.drawable.ic_monero_logo_b);
|
||||
}
|
||||
return logo;
|
||||
}
|
||||
|
@@ -20,16 +20,22 @@ import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.TextInputLayout;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.text.Editable;
|
||||
import android.text.InputType;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
@@ -43,7 +49,6 @@ import com.m2049r.xmrwallet.layout.Toolbar;
|
||||
import com.m2049r.xmrwallet.model.PendingTransaction;
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
import com.m2049r.xmrwallet.model.WalletManager;
|
||||
import com.m2049r.xmrwallet.util.AsyncExchangeRate;
|
||||
import com.m2049r.xmrwallet.util.BarcodeData;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
import com.m2049r.xmrwallet.util.TxData;
|
||||
@@ -134,6 +139,21 @@ public class SendFragment extends Fragment {
|
||||
}
|
||||
});
|
||||
|
||||
etAddress.getEditText().addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable) {
|
||||
etAddress.setError(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
});
|
||||
|
||||
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)) {
|
||||
@@ -147,6 +167,21 @@ public class SendFragment extends Fragment {
|
||||
}
|
||||
});
|
||||
|
||||
etPaymentId.getEditText().addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable) {
|
||||
etPaymentId.setError(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
});
|
||||
|
||||
bPrepareSend.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
@@ -195,8 +230,8 @@ public class SendFragment extends Fragment {
|
||||
public void onClick(View v) {
|
||||
bSend.setEnabled(false);
|
||||
boolean testnet = WalletManager.getInstance().isTestNet();
|
||||
if (!testnet) {
|
||||
//send();
|
||||
if (testnet) {
|
||||
send();
|
||||
} else {
|
||||
etNotes.setEnabled(false);
|
||||
Handler handler = new Handler();
|
||||
@@ -225,6 +260,42 @@ public class SendFragment extends Fragment {
|
||||
}
|
||||
});
|
||||
|
||||
sMixin.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(final AdapterView<?> parentView, View selectedItemView, int position, long id) {
|
||||
parentView.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (isAdded())
|
||||
((TextView) parentView.getChildAt(0)).setTextColor(getResources().getColor(R.color.moneroGray));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parentView) {
|
||||
// nothing (yet?)
|
||||
}
|
||||
});
|
||||
sPriority.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(final AdapterView<?> parentView, View selectedItemView, int position, long id) {
|
||||
parentView.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (isAdded())
|
||||
((TextView) parentView.getChildAt(0)).setTextColor(getResources().getColor(R.color.moneroGray));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parentView) {
|
||||
// nothing (yet?)
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
etDummy.requestFocus();
|
||||
Helper.hideKeyboard(getActivity());
|
||||
|
||||
@@ -347,8 +418,6 @@ public class SendFragment extends Fragment {
|
||||
|
||||
BarcodeData popScannedData();
|
||||
|
||||
void onExchange(AsyncExchangeRate.Listener listener, String currencyA, String currencyB);
|
||||
|
||||
void setSubtitle(String subtitle);
|
||||
|
||||
void setToolbarButton(int type);
|
||||
@@ -388,6 +457,9 @@ public class SendFragment extends Fragment {
|
||||
}
|
||||
if ((data != null) && (data.amount <= 0)) {
|
||||
evAmount.focus();
|
||||
} else {
|
||||
etDummy.requestFocus();
|
||||
Helper.hideKeyboard(getActivity());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -448,4 +520,15 @@ public class SendFragment extends Fragment {
|
||||
pbProgress.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
inflater.inflate(R.menu.send_menu, menu);
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
}
|
||||
}
|
||||
|
@@ -37,13 +37,13 @@ import android.view.MenuItem;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.m2049r.xmrwallet.dialog.DonationFragment;
|
||||
import com.m2049r.xmrwallet.dialog.HelpFragment;
|
||||
import com.m2049r.xmrwallet.layout.Toolbar;
|
||||
import com.m2049r.xmrwallet.model.PendingTransaction;
|
||||
import com.m2049r.xmrwallet.model.TransactionInfo;
|
||||
import com.m2049r.xmrwallet.model.Wallet;
|
||||
import com.m2049r.xmrwallet.model.WalletManager;
|
||||
import com.m2049r.xmrwallet.service.WalletService;
|
||||
import com.m2049r.xmrwallet.util.AsyncExchangeRate;
|
||||
import com.m2049r.xmrwallet.util.BarcodeData;
|
||||
import com.m2049r.xmrwallet.util.Helper;
|
||||
import com.m2049r.xmrwallet.util.TxData;
|
||||
@@ -160,6 +160,18 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
||||
case R.id.action_share:
|
||||
onShareTxInfo();
|
||||
return true;
|
||||
case R.id.action_help_tx_info:
|
||||
HelpFragment.display(getSupportFragmentManager(), R.string.help_tx_details);
|
||||
return true;
|
||||
case R.id.action_help_wallet:
|
||||
HelpFragment.display(getSupportFragmentManager(), R.string.help_wallet);
|
||||
return true;
|
||||
case R.id.action_details_help:
|
||||
HelpFragment.display(getSupportFragmentManager(), R.string.help_details);
|
||||
return true;
|
||||
case R.id.action_help_send:
|
||||
HelpFragment.display(getSupportFragmentManager(), R.string.help_send);
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
@@ -187,6 +199,7 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
||||
public void onButton(int type) {
|
||||
switch (type) {
|
||||
case Toolbar.BUTTON_BACK:
|
||||
onDisposeRequest();
|
||||
onBackPressed();
|
||||
break;
|
||||
case Toolbar.BUTTON_CLOSE:
|
||||
@@ -210,7 +223,7 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
||||
|
||||
Fragment walletFragment = new WalletFragment();
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.add(R.id.fragment_container, walletFragment).commit();
|
||||
.add(R.id.fragment_container, walletFragment, WalletFragment.TAG).commit();
|
||||
Log.d(TAG, "fragment added");
|
||||
|
||||
startWalletService();
|
||||
@@ -376,12 +389,12 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
||||
Log.d(TAG, "onRefreshed()");
|
||||
try {
|
||||
final WalletFragment walletFragment = (WalletFragment)
|
||||
getSupportFragmentManager().findFragmentById(R.id.fragment_container);
|
||||
getSupportFragmentManager().findFragmentByTag(WalletFragment.TAG);
|
||||
if (wallet.isSynchronized()) {
|
||||
Log.d(TAG, "onRefreshed() synced");
|
||||
releaseWakeLock(); // the idea is to stay awake until synced
|
||||
if (!synced) {
|
||||
onProgress(null);
|
||||
if (!synced) { // first sync
|
||||
onProgress(-1);
|
||||
saveWallet(); // save on first sync
|
||||
synced = true;
|
||||
runOnUiThread(new Runnable() {
|
||||
@@ -434,6 +447,16 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
||||
} else {
|
||||
haveWallet = true;
|
||||
invalidateOptionsMenu();
|
||||
|
||||
final WalletFragment walletFragment = (WalletFragment)
|
||||
getSupportFragmentManager().findFragmentById(R.id.fragment_container);
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
if (walletFragment != null) {
|
||||
walletFragment.onLoaded();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -500,10 +523,10 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
||||
public void onProgress(final String text) {
|
||||
try {
|
||||
final WalletFragment walletFragment = (WalletFragment)
|
||||
getSupportFragmentManager().findFragmentById(R.id.fragment_container);
|
||||
getSupportFragmentManager().findFragmentByTag(WalletFragment.TAG);
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
walletFragment.onProgress(text);
|
||||
walletFragment.setProgress(text);
|
||||
}
|
||||
});
|
||||
} catch (ClassCastException ex) {
|
||||
@@ -517,10 +540,10 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
||||
public void onProgress(final int n) {
|
||||
try {
|
||||
final WalletFragment walletFragment = (WalletFragment)
|
||||
getSupportFragmentManager().findFragmentById(R.id.fragment_container);
|
||||
getSupportFragmentManager().findFragmentByTag(WalletFragment.TAG);
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
walletFragment.onProgress(n);
|
||||
walletFragment.setProgress(n);
|
||||
}
|
||||
});
|
||||
} catch (ClassCastException ex) {
|
||||
@@ -782,9 +805,4 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
|
||||
replaceFragment(new ReceiveFragment(), null, extras);
|
||||
Log.d(TAG, "ReceiveFragment placed");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExchange(AsyncExchangeRate.Listener listener, String currencyA, String currencyB) {
|
||||
new AsyncExchangeRate(listener).execute(currencyA, currencyB);
|
||||
}
|
||||
}
|
||||
|
@@ -49,7 +49,7 @@ import java.util.List;
|
||||
public class WalletFragment extends Fragment
|
||||
implements TransactionInfoAdapter.OnInteractionListener,
|
||||
AsyncExchangeRate.Listener {
|
||||
private static final String TAG = "WalletFragment";
|
||||
public static final String TAG = "WalletFragment";
|
||||
private TransactionInfoAdapter adapter;
|
||||
private NumberFormat formatter = NumberFormat.getInstance();
|
||||
|
||||
@@ -96,7 +96,7 @@ public class WalletFragment extends Fragment
|
||||
ivSynced = (ImageView) view.findViewById(R.id.ivSynced);
|
||||
|
||||
sCurrency = (Spinner) view.findViewById(R.id.sCurrency);
|
||||
sCurrency.setAdapter(ArrayAdapter.createFromResource(getContext(), R.array.currency, R.layout.item_spinner));
|
||||
sCurrency.setAdapter(ArrayAdapter.createFromResource(getContext(), R.array.currency, R.layout.item_spinner_balance));
|
||||
|
||||
bSend = (Button) view.findViewById(R.id.bSend);
|
||||
bReceive = (Button) view.findViewById(R.id.bReceive);
|
||||
@@ -244,27 +244,40 @@ public class WalletFragment extends Fragment
|
||||
}
|
||||
}
|
||||
|
||||
public void setProgressText(final String text) {
|
||||
tvProgress.setText(text);
|
||||
boolean walletLoaded = false;
|
||||
|
||||
public void onLoaded() {
|
||||
walletLoaded = true;
|
||||
showReceive();
|
||||
}
|
||||
|
||||
public void onProgress(final String text) {
|
||||
if (text != null) {
|
||||
setProgressText(text);
|
||||
pbProgress.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
pbProgress.setVisibility(View.INVISIBLE);
|
||||
setProgressText(getString(R.string.status_working));
|
||||
onProgress(-1);
|
||||
private void showReceive() {
|
||||
if (walletLoaded) {
|
||||
bReceive.setVisibility(View.VISIBLE);
|
||||
bReceive.setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void onProgress(final int n) {
|
||||
if (n >= 0) {
|
||||
private String syncText = null;
|
||||
|
||||
public void setProgress(final String text) {
|
||||
syncText = text;
|
||||
tvProgress.setText(text);
|
||||
}
|
||||
|
||||
private int syncProgress = -1;
|
||||
|
||||
public void setProgress(final int n) {
|
||||
syncProgress = n;
|
||||
if (n > 100) {
|
||||
pbProgress.setIndeterminate(true);
|
||||
pbProgress.setVisibility(View.VISIBLE);
|
||||
} else if (n >= 0) {
|
||||
pbProgress.setIndeterminate(false);
|
||||
pbProgress.setProgress(n);
|
||||
} else {
|
||||
pbProgress.setIndeterminate(true);
|
||||
pbProgress.setVisibility(View.VISIBLE);
|
||||
} else { // <0
|
||||
pbProgress.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,7 +300,6 @@ public class WalletFragment extends Fragment
|
||||
Log.d(TAG, "updateStatus()");
|
||||
if (walletTitle == null) {
|
||||
setActivityTitle(wallet);
|
||||
onProgress(100); // of loading
|
||||
}
|
||||
long balance = wallet.getBalance();
|
||||
unlockedBalance = wallet.getUnlockedBalance();
|
||||
@@ -295,8 +307,6 @@ public class WalletFragment extends Fragment
|
||||
double amountXmr = Double.parseDouble(Helper.getDisplayAmount(balance - unlockedBalance)); // assume this cannot fail!
|
||||
String unconfirmed = Helper.getFormattedAmount(amountXmr, true);
|
||||
tvUnconfirmedAmount.setText(getResources().getString(R.string.xmr_unconfirmed_amount, unconfirmed));
|
||||
//tvUnconfirmedAmount.setText(getResources().getString(R.string.xmr_unconfirmed_amount,
|
||||
// Helper.getDisplayAmount(balance - unlockedBalance, Helper.DISPLAY_DIGITS_SHORT)));
|
||||
String sync = "";
|
||||
if (!activityCallback.hasBoundService())
|
||||
throw new IllegalStateException("WalletService not bound.");
|
||||
@@ -310,16 +320,18 @@ public class WalletFragment extends Fragment
|
||||
firstBlock = wallet.getBlockChainHeight();
|
||||
}
|
||||
int x = 100 - Math.round(100f * n / (1f * daemonHeight - firstBlock));
|
||||
//onProgress(getString(R.string.status_syncing) + " " + sync);
|
||||
if (x == 0) x = -1;
|
||||
onProgress(x);
|
||||
if (x == 0) x = 101; // indeterminate
|
||||
setProgress(x);
|
||||
ivSynced.setVisibility(View.GONE);
|
||||
} else {
|
||||
sync = getString(R.string.status_synced) + formatter.format(wallet.getBlockChainHeight());
|
||||
ivSynced.setVisibility(View.VISIBLE);
|
||||
}
|
||||
} else {
|
||||
sync = getString(R.string.status_wallet_connecting);
|
||||
setProgress(101);
|
||||
}
|
||||
setProgressText(sync);
|
||||
setProgress(sync);
|
||||
// TODO show connected status somewhere
|
||||
}
|
||||
|
||||
@@ -373,5 +385,8 @@ public class WalletFragment extends Fragment
|
||||
Log.d(TAG, "onResume()");
|
||||
activityCallback.setTitle(walletTitle, walletSubtitle);
|
||||
activityCallback.setToolbarButton(Toolbar.BUTTON_CLOSE);
|
||||
setProgress(syncProgress);
|
||||
setProgress(syncText);
|
||||
showReceive();
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.m2049r.xmrwallet.dialog;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.text.Html;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.m2049r.xmrwallet.BuildConfig;
|
||||
import com.m2049r.xmrwallet.R;
|
||||
|
||||
public class AboutFragment extends DialogFragment {
|
||||
static final String TAG = "AboutFragment";
|
||||
|
||||
public static AboutFragment newInstance() {
|
||||
return new AboutFragment();
|
||||
}
|
||||
|
||||
public static void display(FragmentManager fm) {
|
||||
FragmentTransaction ft = fm.beginTransaction();
|
||||
Fragment prev = fm.findFragmentByTag(TAG);
|
||||
if (prev != null) {
|
||||
ft.remove(prev);
|
||||
}
|
||||
|
||||
AboutFragment.newInstance().show(ft, TAG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_about, null);
|
||||
((TextView) view.findViewById(R.id.tvHelp)).setText(Html.fromHtml(getString(R.string.about_licenses)));
|
||||
((TextView) view.findViewById(R.id.tvVersion)).setText(getString(R.string.about_version, BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE));
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
builder.setView(view);
|
||||
builder.setNegativeButton(R.string.about_close,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
return builder.create();
|
||||
}
|
||||
}
|
@@ -14,82 +14,49 @@
|
||||
* 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);
|
||||
Fragment prev = fm.findFragmentByTag(TAG);
|
||||
if (prev != null) {
|
||||
ft.remove(prev);
|
||||
}
|
||||
ft.addToBackStack(null);
|
||||
|
||||
// Create and show the dialog.
|
||||
DialogFragment newFragment = DonationFragment.newInstance();
|
||||
newFragment.show(ft, FRAGMENT_TAG);
|
||||
DonationFragment.newInstance().show(ft, 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)).
|
||||
(view.findViewById(R.id.bCopyAddress)).
|
||||
setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
|
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
* Copyright 2013 Adam Speakman, m2049r
|
||||
* <p>
|
||||
/*
|
||||
* 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
|
||||
* <p>
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
*
|
||||
* 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.
|
||||
@@ -16,98 +16,57 @@
|
||||
|
||||
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.util.Log;
|
||||
import android.text.Html;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.webkit.WebView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.m2049r.xmrwallet.R;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
/**
|
||||
* Based on LicensesFragment by Adam Speakman on 24/09/13.
|
||||
* http://speakman.net.nz
|
||||
*/
|
||||
public class HelpFragment extends DialogFragment {
|
||||
static final String TAG = "HelpFragment";
|
||||
private static final String FRAGMENT_TAG = "com.m2049r.xmrwallet.dialog.HelpFragment";
|
||||
private static final String HELP_ID = "HELP_ID";
|
||||
|
||||
private AsyncTask<Void, Void, String> loader;
|
||||
|
||||
public static HelpFragment newInstance(int helpResourceId) {
|
||||
HelpFragment fragment = new HelpFragment();
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt(HELP_ID, helpResourceId);
|
||||
fragment.setArguments(bundle);
|
||||
|
||||
return fragment;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fm A fragment manager instance used to display this LicensesFragment.
|
||||
*/
|
||||
public static void displayHelp(FragmentManager fm, int helpResourceId) {
|
||||
public static void display(FragmentManager fm, int helpResourceId) {
|
||||
FragmentTransaction ft = fm.beginTransaction();
|
||||
Fragment prev = fm.findFragmentByTag(FRAGMENT_TAG);
|
||||
Fragment prev = fm.findFragmentByTag(TAG);
|
||||
if (prev != null) {
|
||||
ft.remove(prev);
|
||||
}
|
||||
|
||||
// Create and show the dialog.
|
||||
DialogFragment newFragment = HelpFragment.newInstance(helpResourceId);
|
||||
newFragment.show(ft, FRAGMENT_TAG);
|
||||
HelpFragment.newInstance(helpResourceId).show(ft, TAG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_help, null);
|
||||
|
||||
int helpId = 0;
|
||||
Bundle arguments = getArguments();
|
||||
if (arguments != null) {
|
||||
helpId = arguments.getInt(HELP_ID);
|
||||
}
|
||||
if (helpId > 0)
|
||||
loadHelp(helpId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (loader != null) {
|
||||
loader.cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
private WebView webView;
|
||||
private ProgressBar progress;
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
View content = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_help, null);
|
||||
webView = (WebView) content.findViewById(R.id.helpFragmentWebView);
|
||||
progress = (ProgressBar) content.findViewById(R.id.helpFragmentProgress);
|
||||
((TextView) view.findViewById(R.id.tvHelp)).setText(Html.fromHtml(getString(helpId)));
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
|
||||
builder.setView(content);
|
||||
builder.setView(view);
|
||||
builder.setNegativeButton(R.string.about_close,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
@@ -115,47 +74,6 @@ public class HelpFragment extends DialogFragment {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
private void loadHelp(final int helpResourceId) {
|
||||
// Load asynchronously in case of a very large file.
|
||||
loader = new AsyncTask<Void, Void, String>() {
|
||||
|
||||
@Override
|
||||
protected String doInBackground(Void... params) {
|
||||
InputStream rawResource = getActivity().getResources().openRawResource(helpResourceId);
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(rawResource));
|
||||
|
||||
String line;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
try {
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
sb.append(line);
|
||||
sb.append("\n");
|
||||
}
|
||||
bufferedReader.close();
|
||||
} catch (IOException ex) {
|
||||
Log.e(TAG, ex.getLocalizedMessage());
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String licensesBody) {
|
||||
super.onPostExecute(licensesBody);
|
||||
if (getActivity() == null || isCancelled()) {
|
||||
return;
|
||||
}
|
||||
progress.setVisibility(View.INVISIBLE);
|
||||
webView.setVisibility(View.VISIBLE);
|
||||
webView.loadDataWithBaseURL(null, licensesBody, "text/html", "utf-8", null);
|
||||
loader = null;
|
||||
}
|
||||
|
||||
}.execute();
|
||||
}
|
||||
}
|
@@ -1,165 +0,0 @@
|
||||
/**
|
||||
* Copyright 2013 Adam Speakman, m2049r
|
||||
* <p>
|
||||
* 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
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.m2049r.xmrwallet.dialog;
|
||||
|
||||
import android.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.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.webkit.WebView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.m2049r.xmrwallet.BuildConfig;
|
||||
import com.m2049r.xmrwallet.R;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
/**
|
||||
* Created by Adam Speakman on 24/09/13.
|
||||
* http://speakman.net.nz
|
||||
*/
|
||||
public class LicensesFragment extends DialogFragment {
|
||||
static final String TAG = "LicensesFragment";
|
||||
int versionCode = BuildConfig.VERSION_CODE;
|
||||
String versionName = BuildConfig.VERSION_NAME;
|
||||
|
||||
private AsyncTask<Void, Void, String> mLicenseLoader;
|
||||
|
||||
private static final String FRAGMENT_TAG = "com.m2049r.xmrwalelt.dialog.LicensesFragment";
|
||||
|
||||
/**
|
||||
* Creates a new instance of LicensesFragment with no Close button.
|
||||
*
|
||||
* @return A new licenses fragment.
|
||||
*/
|
||||
public static LicensesFragment newInstance() {
|
||||
return new LicensesFragment();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 displayLicensesFragment(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 = LicensesFragment.newInstance();
|
||||
newFragment.show(ft, FRAGMENT_TAG);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
loadLicenses();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (mLicenseLoader != null) {
|
||||
mLicenseLoader.cancel(true);
|
||||
}
|
||||
}
|
||||
|
||||
private WebView mWebView;
|
||||
private ProgressBar mIndeterminateProgress;
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
View content = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_licenses, null);
|
||||
mWebView = (WebView) content.findViewById(R.id.licensesFragmentWebView);
|
||||
mIndeterminateProgress = (ProgressBar) content.findViewById(R.id.licensesFragmentIndeterminateProgress);
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
|
||||
TextView text = (TextView) content.findViewById(R.id.licensesFragmentText);
|
||||
text.setText(getString(R.string.about_text, versionName, versionCode));
|
||||
|
||||
builder.setView(content);
|
||||
builder.setNegativeButton(R.string.about_close,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
private void loadLicenses() {
|
||||
// Load asynchronously in case of a very large file.
|
||||
mLicenseLoader = new AsyncTask<Void, Void, String>() {
|
||||
|
||||
@Override
|
||||
protected String doInBackground(Void... params) {
|
||||
InputStream rawResource = getActivity().getResources().openRawResource(R.raw.licenses);
|
||||
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(rawResource));
|
||||
|
||||
String line;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
try {
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
sb.append(line);
|
||||
sb.append("\n");
|
||||
}
|
||||
bufferedReader.close();
|
||||
} catch (IOException ex) {
|
||||
Log.e(TAG, ex.getLocalizedMessage());
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String licensesBody) {
|
||||
super.onPostExecute(licensesBody);
|
||||
if (getActivity() == null || isCancelled()) {
|
||||
return;
|
||||
}
|
||||
mIndeterminateProgress.setVisibility(View.INVISIBLE);
|
||||
mWebView.setVisibility(View.VISIBLE);
|
||||
mWebView.loadDataWithBaseURL(null, licensesBody, "text/html", "utf-8", null);
|
||||
mLicenseLoader = null;
|
||||
}
|
||||
|
||||
}.execute();
|
||||
}
|
||||
}
|
@@ -14,13 +14,8 @@
|
||||
* 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;
|
||||
@@ -32,47 +27,27 @@ 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);
|
||||
Fragment prev = fm.findFragmentByTag(TAG);
|
||||
if (prev != null) {
|
||||
ft.remove(prev);
|
||||
}
|
||||
ft.addToBackStack(null);
|
||||
|
||||
// Create and show the dialog.
|
||||
DialogFragment newFragment = PrivacyFragment.newInstance();
|
||||
newFragment.show(ft, FRAGMENT_TAG);
|
||||
PrivacyFragment.newInstance().show(ft, TAG);
|
||||
}
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_privacy_policy, null);
|
||||
|
@@ -179,10 +179,16 @@ public class ExchangeView extends LinearLayout implements AsyncExchangeRate.List
|
||||
|
||||
sCurrencyB.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
|
||||
public void onItemSelected(final AdapterView<?> parentView, View selectedItemView, int position, long id) {
|
||||
if (position != 0) { // if not XMR, select XMR on other
|
||||
sCurrencyA.setSelection(0, true);
|
||||
}
|
||||
parentView.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
((TextView) parentView.getChildAt(0)).setTextColor(getResources().getColor(R.color.moneroGray));
|
||||
}
|
||||
});
|
||||
doExchange();
|
||||
}
|
||||
|
||||
@@ -265,10 +271,6 @@ public class ExchangeView extends LinearLayout implements AsyncExchangeRate.List
|
||||
return ok;
|
||||
}
|
||||
|
||||
int selectedNotXmrCurrency() {
|
||||
return Math.max(getCurrencyA(), getCurrencyB());
|
||||
}
|
||||
|
||||
public void doExchange() {
|
||||
tvAmountB.setText("--");
|
||||
// TODO cache & use cached exchange rate here
|
||||
@@ -284,6 +286,7 @@ public class ExchangeView extends LinearLayout implements AsyncExchangeRate.List
|
||||
|
||||
public void exchange(double rate) {
|
||||
if (getCurrencyA() == 0) {
|
||||
if (xmrAmount == null) return;
|
||||
if (!xmrAmount.isEmpty() && (rate > 0)) {
|
||||
double amountB = rate * Double.parseDouble(xmrAmount);
|
||||
notXmrAmount = Helper.getFormattedAmount(amountB, getCurrencyB() == 0);
|
||||
@@ -292,6 +295,7 @@ public class ExchangeView extends LinearLayout implements AsyncExchangeRate.List
|
||||
}
|
||||
tvAmountB.setText(notXmrAmount);
|
||||
} else if (getCurrencyB() == 0) {
|
||||
if (notXmrAmount == null) return;
|
||||
if (!notXmrAmount.isEmpty() && (rate > 0)) {
|
||||
double amountB = rate * Double.parseDouble(notXmrAmount);
|
||||
setXmr(Helper.getFormattedAmount(amountB, true));
|
||||
@@ -349,7 +353,9 @@ public class ExchangeView extends LinearLayout implements AsyncExchangeRate.List
|
||||
public void exchangeFailed() {
|
||||
hideProgress();
|
||||
exchange(0);
|
||||
// TODO Toast it failed - I think this happens elsewhere already
|
||||
if (onFailedExchangeListener != null) {
|
||||
onFailedExchangeListener.onFailedExchange();
|
||||
}
|
||||
}
|
||||
|
||||
// callback from AsyncExchangeRate when we have a rate
|
||||
|
@@ -19,6 +19,7 @@
|
||||
package com.m2049r.xmrwallet.layout;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -79,6 +80,12 @@ public class Toolbar extends android.support.v7.widget.Toolbar {
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
toolbarImage = (ImageView) findViewById(R.id.toolbarImage);
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
|
||||
// the vector image does not work well for androis < Nougat
|
||||
toolbarImage.getLayoutParams().width = (int) getResources().getDimension(R.dimen.logo_width);
|
||||
toolbarImage.setImageResource(R.drawable.logo_horizontol_xmrujo);
|
||||
}
|
||||
|
||||
toolbarTitle = (TextView) findViewById(R.id.toolbarTitle);
|
||||
toolbarSubtitle = (TextView) findViewById(R.id.toolbarSubtitle);
|
||||
bDonate = (Button) findViewById(R.id.bDonate);
|
||||
|
@@ -103,6 +103,7 @@ public class WalletInfoAdapter extends RecyclerView.Adapter<WalletInfoAdapter.Vi
|
||||
final TextView tvAddress;
|
||||
final ImageButton ibOptions;
|
||||
WalletManager.WalletInfo infoItem;
|
||||
boolean popupOpen = false;
|
||||
|
||||
ViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
@@ -112,10 +113,12 @@ public class WalletInfoAdapter extends RecyclerView.Adapter<WalletInfoAdapter.Vi
|
||||
ibOptions.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (popupOpen) return;
|
||||
//creating a popup menu
|
||||
PopupMenu popup = new PopupMenu(context, ibOptions);
|
||||
//inflating menu from xml resource
|
||||
popup.inflate(R.menu.list_context_menu);
|
||||
popupOpen = true;
|
||||
//adding click listener
|
||||
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
||||
@Override
|
||||
@@ -128,6 +131,12 @@ public class WalletInfoAdapter extends RecyclerView.Adapter<WalletInfoAdapter.Vi
|
||||
});
|
||||
//displaying the popup
|
||||
popup.show();
|
||||
popup.setOnDismissListener(new PopupMenu.OnDismissListener() {
|
||||
@Override
|
||||
public void onDismiss(PopupMenu menu) {
|
||||
popupOpen = false;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
|
@@ -333,7 +333,8 @@ public class WalletService extends Service {
|
||||
Wallet myWallet = getWallet();
|
||||
Log.d(TAG, "SEND TX for wallet: " + myWallet.getName());
|
||||
PendingTransaction pendingTransaction = myWallet.getPendingTransaction();
|
||||
if (pendingTransaction.getStatus() != PendingTransaction.Status.Status_Ok) {
|
||||
if ((pendingTransaction == null)
|
||||
|| (pendingTransaction.getStatus() != PendingTransaction.Status.Status_Ok)) {
|
||||
Log.e(TAG, "PendingTransaction is " + pendingTransaction.getStatus());
|
||||
myWallet.disposePendingTransaction(); // it's broken anyway
|
||||
if (observer != null) observer.onSentTransaction(false);
|
||||
@@ -480,7 +481,7 @@ public class WalletService extends Service {
|
||||
showProgress(100);
|
||||
}
|
||||
showProgress(getString(R.string.status_wallet_connecting));
|
||||
showProgress(-1);
|
||||
showProgress(101);
|
||||
// if we try to refresh the history here we get occasional segfaults!
|
||||
// doesnt matter since we update as soon as we get a new block anyway
|
||||
Log.d(TAG, "start() done");
|
||||
|
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="@color/moneroText" android:state_enabled="false" />
|
||||
<item android:color="@color/moneroWhite" />
|
||||
</selector>
|
12
app/src/main/res/drawable/backgound_spinner_gray.xml
Normal file
12
app/src/main/res/drawable/backgound_spinner_gray.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<padding
|
||||
android:bottom="8dp"
|
||||
android:left="8dp"
|
||||
android:right="8dp"
|
||||
android:top="8dp" />
|
||||
<stroke
|
||||
android:width="2dp"
|
||||
android:color="@color/moneroGray" />
|
||||
</shape>
|
@@ -17,11 +17,11 @@
|
||||
9.24995106,8.48677287 C9.24995106,5.61623564 11.5770468,3.28929415
|
||||
14.4474298,3.28929415 C17.3178128,3.28929415 19.6449085,5.61623564
|
||||
19.6449085,8.48677287 C19.6449085,11.3571559 17.3178128,13.6840973
|
||||
14.4474298,13.6840973 M14.4474298,-4.62765957e-05 C8.23695638,-4.62765957e-05
|
||||
2.82706809,3.42395904 3.08510638e-05,8.48692713 C2.82706809,13.5494324
|
||||
14.4474298,13.6840973 M14.4474298,-0.0000463 C8.23695638,-0.0000463
|
||||
2.82706809,3.42395904 0.0000309,8.48692713 C2.82706809,13.5494324
|
||||
8.23695638,16.9734378 14.4474298,16.9734378 C20.6579032,16.9734378
|
||||
26.0676372,13.5494324 28.8948287,8.48692713 C26.0676372,3.42395904
|
||||
20.6579032,-4.62765957e-05 14.4474298,-4.62765957e-05"
|
||||
20.6579032,-0.0000463 14.4474298,-0.0000463"
|
||||
android:strokeWidth="1" />
|
||||
</group>
|
||||
</group>
|
||||
|
BIN
app/src/main/res/drawable/ic_monero_logo_b.png
Normal file
BIN
app/src/main/res/drawable/ic_monero_logo_b.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
File diff suppressed because one or more lines are too long
13
app/src/main/res/drawable/ic_statsup.xml
Normal file
13
app/src/main/res/drawable/ic_statsup.xml
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
BIN
app/src/main/res/drawable/logo_horizontol_xmrujo.png
Normal file
BIN
app/src/main/res/drawable/logo_horizontol_xmrujo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.6 KiB |
@@ -10,7 +10,7 @@
|
||||
android:id="@+id/toolbar"
|
||||
style="@style/ToolBarStyle.Event"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="@drawable/backgound_toolbar_mainnet"
|
||||
android:minHeight="?attr/actionBarSize" />
|
||||
|
||||
|
@@ -10,7 +10,7 @@
|
||||
android:id="@+id/toolbar"
|
||||
style="@style/ToolBarStyle.Event"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="@drawable/backgound_toolbar_mainnet"
|
||||
android:minHeight="?attr/actionBarSize" />
|
||||
|
||||
|
39
app/src/main/res/layout/fragment_about.xml
Normal file
39
app/src/main/res/layout/fragment_about.xml
Normal file
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingEnd="16dp"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingTop="8dp">
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:src="@mipmap/ic_launcher" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvVersion"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:text="@string/about_version" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvHelp"
|
||||
style="@style/MoneroText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/header_top"
|
||||
android:layout_marginBottom="@dimen/header_top"
|
||||
android:gravity="start"
|
||||
android:textSize="10sp"
|
||||
tools:text="@string/menu_help" />
|
||||
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
@@ -2,9 +2,9 @@
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="8sp"
|
||||
android:paddingEnd="16sp"
|
||||
android:paddingStart="16sp">
|
||||
android:paddingTop="8dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:paddingStart="16dp">
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="100sp"
|
||||
android:layout_height="100dp"
|
||||
android:src="@drawable/gunther_donate" />
|
||||
|
||||
<TextView
|
||||
|
@@ -3,7 +3,7 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="8sp">
|
||||
android:layout_margin="8dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
@@ -1,29 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingEnd="16dp"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingTop="8dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/helpFragmentIcon"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@mipmap/ic_launcher"
|
||||
android:padding="8sp"/>
|
||||
android:orientation="vertical">
|
||||
|
||||
<WebView
|
||||
android:id="@+id/helpFragmentWebView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@+id/helpFragmentIcon"
|
||||
android:visibility="invisible" />
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:src="@mipmap/ic_launcher" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/helpFragmentProgress"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:indeterminate="true" />
|
||||
<TextView
|
||||
android:id="@+id/tvHelp"
|
||||
style="@style/MoneroText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/header_top"
|
||||
android:autoLink="web"
|
||||
android:gravity="start"
|
||||
android:textSize="14sp"
|
||||
tools:text="@string/menu_help" />
|
||||
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user