Mostly Help "System" (#112)

* help & new exchange icon

* layout tweaks + removed nocopy icons

* sync help

* hide keyboard on spend

* QR Recieve => Receive

* menu tweaking

* use png logo for android < nougat

* gray generate

* position tweak in toolbar

* new exchange icon for wallet balance

* new About Dialog

* enable sending on mainnet

* new version 1.1.6

* dispose transaction on back

* remove unused onExchange method

* gray stuff + some tweaks

* new logo for qr
This commit is contained in:
m2049r
2017-11-04 00:43:24 +01:00
committed by GitHub
parent d3beb7ca3f
commit d67e02cbcb
39 changed files with 993 additions and 1079 deletions
@@ -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) {
@@ -47,9 +47,9 @@ import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.m2049r.xmrwallet.dialog.DonationFragment;
import com.m2049r.xmrwallet.dialog.AboutFragment;
import com.m2049r.xmrwallet.dialog.HelpFragment;
import com.m2049r.xmrwallet.dialog.LicensesFragment;
import com.m2049r.xmrwallet.dialog.DonationFragment;
import com.m2049r.xmrwallet.dialog.PrivacyFragment;
import com.m2049r.xmrwallet.layout.Toolbar;
import com.m2049r.xmrwallet.model.Wallet;
@@ -1053,14 +1053,23 @@ 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.displayHelp(getSupportFragmentManager(), R.string.help_create_new);
return true;
case R.id.action_create_help_keys:
HelpFragment.displayHelp(getSupportFragmentManager(), R.string.help_create_keys);
return true;
case R.id.action_create_help_view:
HelpFragment.displayHelp(getSupportFragmentManager(), R.string.help_create_view);
return true;
case R.id.action_create_help_seed:
HelpFragment.displayHelp(getSupportFragmentManager(), R.string.help_create_seed);
return true;
case R.id.action_details_help:
HelpFragment.displayHelp(getSupportFragmentManager(), R.raw.help_details);
HelpFragment.displayHelp(getSupportFragmentManager(), R.string.help_details);
return true;
case R.id.action_license_info:
LicensesFragment.displayLicensesFragment(getSupportFragmentManager());
AboutFragment.displayHelp(getSupportFragmentManager(), R.string.about_licenses);
return true;
case R.id.action_privacy_policy:
PrivacyFragment.display(getSupportFragmentManager());
@@ -112,13 +112,6 @@ public class ReceiveFragment extends Fragment {
generateQr();
}
});
/*
evAmount.setOnAmountInvalidatedListener(new ExchangeView.OnAmountInvalidatedListener() {
@Override
public void onAmountInvalidated() {
clearQR();
}
});
evAmount.setOnFailedExchangeListener(new ExchangeView.OnFailedExchangeListener() {
@Override
@@ -126,7 +119,7 @@ public class ReceiveFragment extends Fragment {
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 +366,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;
}
@@ -30,6 +30,7 @@ import android.view.LayoutInflater;
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 +44,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;
@@ -195,8 +195,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 +225,30 @@ public class SendFragment extends Fragment {
}
});
sMixin.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
((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(AdapterView<?> parentView, View selectedItemView, int position, long id) {
((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 +371,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 +410,9 @@ public class SendFragment extends Fragment {
}
if ((data != null) && (data.amount <= 0)) {
evAmount.focus();
} else {
etDummy.requestFocus();
Helper.hideKeyboard(getActivity());
}
}
@@ -36,6 +36,7 @@ import android.util.Log;
import android.view.MenuItem;
import android.widget.Toast;
import com.m2049r.xmrwallet.dialog.HelpFragment;
import com.m2049r.xmrwallet.dialog.DonationFragment;
import com.m2049r.xmrwallet.layout.Toolbar;
import com.m2049r.xmrwallet.model.PendingTransaction;
@@ -160,6 +161,12 @@ public class WalletActivity extends AppCompatActivity implements WalletFragment.
case R.id.action_share:
onShareTxInfo();
return true;
case R.id.action_help_tx_info:
HelpFragment.displayHelp(getSupportFragmentManager(), R.string.help_tx_details);
return true;
case R.id.action_help_sync:
HelpFragment.displayHelp(getSupportFragmentManager(), R.string.help_sync);
return true;
default:
return super.onOptionsItemSelected(item);
}
@@ -187,6 +194,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:
@@ -782,9 +790,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);
}
}
@@ -0,0 +1,85 @@
/*
* 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 = "HelpFragment";
private static final String HELP_ID = "HELP_ID";
public static AboutFragment newInstance(int helpResourceId) {
AboutFragment fragment = new AboutFragment();
Bundle bundle = new Bundle();
bundle.putInt(HELP_ID, helpResourceId);
fragment.setArguments(bundle);
return fragment;
}
public static void displayHelp(FragmentManager fm, int helpResourceId) {
FragmentTransaction ft = fm.beginTransaction();
Fragment prev = fm.findFragmentByTag(TAG);
if (prev != null) {
ft.remove(prev);
}
DialogFragment helpFragment = AboutFragment.newInstance(helpResourceId);
helpFragment.show(ft, TAG);
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_about, null);
int helpId = 0;
Bundle arguments = getArguments();
if (arguments != null) {
helpId = arguments.getInt(HELP_ID);
}
if (helpId > 0) {
((TextView) view.findViewById(R.id.tvHelp)).setText(Html.fromHtml(getString(helpId)));
}
TextView text = (TextView) view.findViewById(R.id.tvVersion);
text.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();
}
}
@@ -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,58 @@
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) {
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);
DialogFragment helpFragment = HelpFragment.newInstance(helpResourceId);
helpFragment.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 +75,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();
}
}
@@ -183,6 +183,7 @@ public class ExchangeView extends LinearLayout implements AsyncExchangeRate.List
if (position != 0) { // if not XMR, select XMR on other
sCurrencyA.setSelection(0, true);
}
((TextView) parentView.getChildAt(0)).setTextColor(getResources().getColor(R.color.moneroGray));
doExchange();
}
@@ -265,10 +266,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
@@ -351,7 +348,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);