|
|
|
@ -28,10 +28,21 @@ import android.os.Bundle;
|
|
|
|
|
import android.os.IBinder;
|
|
|
|
|
import android.os.PowerManager;
|
|
|
|
|
import android.support.annotation.NonNull;
|
|
|
|
|
import android.support.design.widget.NavigationView;
|
|
|
|
|
import android.support.v4.app.Fragment;
|
|
|
|
|
import android.support.v4.app.FragmentManager;
|
|
|
|
|
import android.support.v4.app.FragmentTransaction;
|
|
|
|
|
import android.support.v4.view.GravityCompat;
|
|
|
|
|
import android.support.v4.widget.DrawerLayout;
|
|
|
|
|
import android.support.v7.app.ActionBarDrawerToggle;
|
|
|
|
|
import android.view.KeyEvent;
|
|
|
|
|
import android.view.LayoutInflater;
|
|
|
|
|
import android.view.Menu;
|
|
|
|
|
import android.view.MenuItem;
|
|
|
|
|
import android.view.View;
|
|
|
|
|
import android.view.inputmethod.EditorInfo;
|
|
|
|
|
import android.widget.EditText;
|
|
|
|
|
import android.widget.TextView;
|
|
|
|
|
import android.widget.Toast;
|
|
|
|
|
|
|
|
|
|
import com.m2049r.xmrwallet.data.BarcodeData;
|
|
|
|
@ -49,6 +60,9 @@ import com.m2049r.xmrwallet.util.Helper;
|
|
|
|
|
import com.m2049r.xmrwallet.util.UserNotes;
|
|
|
|
|
import com.m2049r.xmrwallet.widget.Toolbar;
|
|
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
|
|
import timber.log.Timber;
|
|
|
|
|
|
|
|
|
|
public class WalletActivity extends SecureActivity implements WalletFragment.Listener,
|
|
|
|
@ -57,12 +71,18 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
|
|
|
|
GenerateReviewFragment.Listener,
|
|
|
|
|
GenerateReviewFragment.PasswordChangedListener,
|
|
|
|
|
ScannerFragment.OnScannedListener, ReceiveFragment.Listener,
|
|
|
|
|
SendAddressWizardFragment.OnScanListener {
|
|
|
|
|
SendAddressWizardFragment.OnScanListener,
|
|
|
|
|
WalletFragment.DrawerLocker,
|
|
|
|
|
NavigationView.OnNavigationItemSelectedListener {
|
|
|
|
|
|
|
|
|
|
public static final String REQUEST_ID = "id";
|
|
|
|
|
public static final String REQUEST_PW = "pw";
|
|
|
|
|
public static final String REQUEST_FINGERPRINT_USED = "fingerprint";
|
|
|
|
|
|
|
|
|
|
private NavigationView accountsView;
|
|
|
|
|
private DrawerLayout drawer;
|
|
|
|
|
private ActionBarDrawerToggle drawerToggle;
|
|
|
|
|
|
|
|
|
|
private Toolbar toolbar;
|
|
|
|
|
private boolean needVerifyIdentity;
|
|
|
|
|
|
|
|
|
@ -155,10 +175,11 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
|
|
|
|
@Override
|
|
|
|
|
protected void onDestroy() {
|
|
|
|
|
Timber.d("onDestroy()");
|
|
|
|
|
if ((mBoundService != null) && !isSynced() && (getWallet() != null)) {
|
|
|
|
|
if ((mBoundService != null) && (getWallet() != null)) {
|
|
|
|
|
saveWallet();
|
|
|
|
|
}
|
|
|
|
|
stopWalletService();
|
|
|
|
|
drawer.removeDrawerListener(drawerToggle);
|
|
|
|
|
super.onDestroy();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -167,6 +188,14 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
|
|
|
|
return haveWallet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean onPrepareOptionsMenu(Menu menu) {
|
|
|
|
|
MenuItem renameItem = menu.findItem(R.id.action_rename);
|
|
|
|
|
if (renameItem != null)
|
|
|
|
|
renameItem.setVisible(hasWallet() && getWallet().isSynchronized());
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean onOptionsItemSelected(MenuItem item) {
|
|
|
|
|
switch (item.getItemId()) {
|
|
|
|
@ -194,6 +223,9 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
|
|
|
|
case R.id.action_help_send:
|
|
|
|
|
HelpFragment.display(getSupportFragmentManager(), R.string.help_send);
|
|
|
|
|
return true;
|
|
|
|
|
case R.id.action_rename:
|
|
|
|
|
onAccountRename();
|
|
|
|
|
return true;
|
|
|
|
|
default:
|
|
|
|
|
return super.onOptionsItemSelected(item);
|
|
|
|
|
}
|
|
|
|
@ -253,6 +285,16 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
|
|
|
|
|
drawerToggle = new ActionBarDrawerToggle(this, drawer, toolbar,
|
|
|
|
|
R.string.accounts_drawer_open, R.string.accounts_drawer_close);
|
|
|
|
|
drawer.addDrawerListener(drawerToggle);
|
|
|
|
|
drawerToggle.syncState();
|
|
|
|
|
setDrawerEnabled(false); // disable until synced
|
|
|
|
|
|
|
|
|
|
accountsView = (NavigationView) findViewById(R.id.accounts_nav);
|
|
|
|
|
accountsView.setNavigationItemSelectedListener(this);
|
|
|
|
|
|
|
|
|
|
showNet();
|
|
|
|
|
|
|
|
|
|
Fragment walletFragment = new WalletFragment();
|
|
|
|
@ -280,7 +322,6 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Wallet getWallet() {
|
|
|
|
|
if (mBoundService == null) throw new IllegalStateException("WalletService not bound.");
|
|
|
|
|
return mBoundService.getWallet();
|
|
|
|
@ -444,10 +485,20 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
|
|
|
|
// WalletService.Observer
|
|
|
|
|
///////////////////////////
|
|
|
|
|
|
|
|
|
|
private int numAccounts = -1;
|
|
|
|
|
|
|
|
|
|
// refresh and return true if successful
|
|
|
|
|
@Override
|
|
|
|
|
public boolean onRefreshed(final Wallet wallet, final boolean full) {
|
|
|
|
|
Timber.d("onRefreshed()");
|
|
|
|
|
if (numAccounts != wallet.numAccounts()) {
|
|
|
|
|
numAccounts = wallet.numAccounts();
|
|
|
|
|
runOnUiThread(new Runnable() {
|
|
|
|
|
public void run() {
|
|
|
|
|
updateAccountsList();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
final WalletFragment walletFragment = (WalletFragment)
|
|
|
|
|
getSupportFragmentManager().findFragmentByTag(WalletFragment.class.getName());
|
|
|
|
@ -869,6 +920,11 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onBackPressed() {
|
|
|
|
|
if (drawer.isDrawerOpen(GravityCompat.START)) {
|
|
|
|
|
drawer.closeDrawer(GravityCompat.START);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
final Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
|
|
|
|
|
if (fragment instanceof OnBackPressedListener) {
|
|
|
|
|
if (!((OnBackPressedListener) fragment).onBackPressed()) {
|
|
|
|
@ -889,4 +945,128 @@ public class WalletActivity extends SecureActivity implements WalletFragment.Lis
|
|
|
|
|
return getPreferences(Context.MODE_PRIVATE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<Integer> accountIds = new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
// generate and cache unique ids for use in accounts list
|
|
|
|
|
private int getAccountId(int accountIndex) {
|
|
|
|
|
final int n = accountIds.size();
|
|
|
|
|
for (int i = n; i <= accountIndex; i++) {
|
|
|
|
|
accountIds.add(View.generateViewId());
|
|
|
|
|
}
|
|
|
|
|
return accountIds.get(accountIndex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// drawer stuff
|
|
|
|
|
void updateAccountsList() {
|
|
|
|
|
final Wallet wallet = getWallet();
|
|
|
|
|
final TextView tvName = (TextView) accountsView.getHeaderView(0).findViewById(R.id.tvName);
|
|
|
|
|
tvName.setText(wallet.getName());
|
|
|
|
|
final TextView tvBalance = (TextView) accountsView.getHeaderView(0).findViewById(R.id.tvBalance);
|
|
|
|
|
tvBalance.setText(getString(R.string.accounts_balance,
|
|
|
|
|
Helper.getDisplayAmount(wallet.getBalanceAll() + wallet.getUnlockedBalanceAll(),
|
|
|
|
|
5)));
|
|
|
|
|
Menu menu = accountsView.getMenu();
|
|
|
|
|
menu.removeGroup(R.id.accounts_list);
|
|
|
|
|
for (int i = 0; i < wallet.numAccounts(); i++) {
|
|
|
|
|
final String label = wallet.getAccountLabel(i);
|
|
|
|
|
final MenuItem item = menu.add(R.id.accounts_list, getAccountId(i), 2 * i, label);
|
|
|
|
|
item.setIcon(R.drawable.ic_account_balance_wallet_black_24dp);
|
|
|
|
|
if (i == wallet.getAccountIndex())
|
|
|
|
|
item.setChecked(true);
|
|
|
|
|
}
|
|
|
|
|
menu.setGroupCheckable(R.id.accounts_list, true, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void setDrawerEnabled(boolean enabled) {
|
|
|
|
|
Timber.d("setDrawerEnabled %b", enabled);
|
|
|
|
|
final int lockMode = enabled ? DrawerLayout.LOCK_MODE_UNLOCKED :
|
|
|
|
|
DrawerLayout.LOCK_MODE_LOCKED_CLOSED;
|
|
|
|
|
drawer.setDrawerLockMode(lockMode);
|
|
|
|
|
drawerToggle.setDrawerIndicatorEnabled(enabled);
|
|
|
|
|
invalidateOptionsMenu(); // menu may need to be changed
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void updateAccountName() {
|
|
|
|
|
setSubtitle(getWallet().getAccountLabel());
|
|
|
|
|
updateAccountsList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void onAccountRename() {
|
|
|
|
|
final LayoutInflater li = LayoutInflater.from(this);
|
|
|
|
|
final View promptsView = li.inflate(R.layout.prompt_rename, null);
|
|
|
|
|
|
|
|
|
|
final AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
|
|
|
|
|
alertDialogBuilder.setView(promptsView);
|
|
|
|
|
|
|
|
|
|
final EditText etRename = (EditText) promptsView.findViewById(R.id.etRename);
|
|
|
|
|
final TextView tvRenameLabel = (TextView) promptsView.findViewById(R.id.tvRenameLabel);
|
|
|
|
|
final Wallet wallet = getWallet();
|
|
|
|
|
tvRenameLabel.setText(getString(R.string.prompt_rename, wallet.getAccountLabel()));
|
|
|
|
|
|
|
|
|
|
// set dialog message
|
|
|
|
|
alertDialogBuilder
|
|
|
|
|
.setCancelable(false)
|
|
|
|
|
.setPositiveButton(getString(R.string.label_ok),
|
|
|
|
|
new DialogInterface.OnClickListener() {
|
|
|
|
|
public void onClick(DialogInterface dialog, int id) {
|
|
|
|
|
Helper.hideKeyboardAlways(WalletActivity.this);
|
|
|
|
|
String newName = etRename.getText().toString();
|
|
|
|
|
wallet.setAccountLabel(newName);
|
|
|
|
|
updateAccountName();
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.setNegativeButton(getString(R.string.label_cancel),
|
|
|
|
|
new DialogInterface.OnClickListener() {
|
|
|
|
|
public void onClick(DialogInterface dialog, int id) {
|
|
|
|
|
Helper.hideKeyboardAlways(WalletActivity.this);
|
|
|
|
|
dialog.cancel();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
final AlertDialog dialog = alertDialogBuilder.create();
|
|
|
|
|
Helper.showKeyboard(dialog);
|
|
|
|
|
|
|
|
|
|
// accept keyboard "ok"
|
|
|
|
|
etRename.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)) {
|
|
|
|
|
Helper.hideKeyboardAlways(WalletActivity.this);
|
|
|
|
|
String newName = etRename.getText().toString();
|
|
|
|
|
dialog.cancel();
|
|
|
|
|
wallet.setAccountLabel(newName);
|
|
|
|
|
updateAccountName();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
dialog.show();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean onNavigationItemSelected(MenuItem item) {
|
|
|
|
|
final int id = item.getItemId();
|
|
|
|
|
switch (id) {
|
|
|
|
|
case R.id.account_new:
|
|
|
|
|
getWallet().addAccount();
|
|
|
|
|
int newIdx = getWallet().numAccounts() - 1;
|
|
|
|
|
getWallet().setAccountIndex(newIdx);
|
|
|
|
|
Toast.makeText(this,
|
|
|
|
|
getString(R.string.accounts_new, newIdx),
|
|
|
|
|
Toast.LENGTH_SHORT).show();
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
Timber.d("NavigationDrawer ID=%d", id);
|
|
|
|
|
int accountIdx = accountIds.indexOf(id);
|
|
|
|
|
if (accountIdx >= 0) {
|
|
|
|
|
Timber.d("found @%d", accountIdx);
|
|
|
|
|
getWallet().setAccountIndex(accountIdx);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
forceUpdate();
|
|
|
|
|
drawer.closeDrawer(GravityCompat.START);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|