From 00852da9f75e0c18417e2b3f856325cd3a2d92e4 Mon Sep 17 00:00:00 2001 From: m2049r <30435443+m2049r@users.noreply.github.com> Date: Fri, 29 Sep 2017 19:18:07 +0200 Subject: [PATCH] Add some Help (#90) * simple help for create wallet * toast that selecting seed or spendkey is not allowed --- .idea/.gitignore | 1 + .idea/misc.xml | 46 ----- .../m2049r/xmrwallet/GenerateFragment.java | 14 ++ .../xmrwallet/GenerateReviewFragment.java | 15 ++ .../com/m2049r/xmrwallet/LoginActivity.java | 8 +- .../m2049r/xmrwallet/dialog/HelpFragment.java | 160 ++++++++++++++++++ .../{license => dialog}/LicensesFragment.java | 66 ++------ .../main/res/drawable/ic_help_black_24dp.xml | 9 + app/src/main/res/layout/help_fragment.xml | 29 ++++ app/src/main/res/layout/licenses_fragment.xml | 8 +- app/src/main/res/menu/create_wallet_menu.xml | 12 ++ app/src/main/res/raw/help_create.html | 38 +++++ app/src/main/res/values/strings.xml | 4 + 13 files changed, 301 insertions(+), 109 deletions(-) delete mode 100644 .idea/misc.xml create mode 100644 app/src/main/java/com/m2049r/xmrwallet/dialog/HelpFragment.java rename app/src/main/java/com/m2049r/xmrwallet/{license => dialog}/LicensesFragment.java (69%) create mode 100644 app/src/main/res/drawable/ic_help_black_24dp.xml create mode 100644 app/src/main/res/layout/help_fragment.xml create mode 100644 app/src/main/res/menu/create_wallet_menu.xml create mode 100644 app/src/main/res/raw/help_create.html diff --git a/.idea/.gitignore b/.idea/.gitignore index 45c1d3be..05cc59ca 100644 --- a/.idea/.gitignore +++ b/.idea/.gitignore @@ -1,2 +1,3 @@ workspace.xml markdown-* +misc.xml diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 5d199810..00000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/java/com/m2049r/xmrwallet/GenerateFragment.java b/app/src/main/java/com/m2049r/xmrwallet/GenerateFragment.java index b728524b..8d7c6431 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/GenerateFragment.java +++ b/app/src/main/java/com/m2049r/xmrwallet/GenerateFragment.java @@ -18,6 +18,7 @@ package com.m2049r.xmrwallet; import android.content.Context; import android.os.Bundle; +import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.text.Editable; import android.text.InputType; @@ -25,6 +26,8 @@ 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; @@ -379,4 +382,15 @@ public class GenerateFragment extends Fragment { } } + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setHasOptionsMenu(true); + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + inflater.inflate(R.menu.create_wallet_menu, menu); + super.onCreateOptionsMenu(menu, inflater); + } } diff --git a/app/src/main/java/com/m2049r/xmrwallet/GenerateReviewFragment.java b/app/src/main/java/com/m2049r/xmrwallet/GenerateReviewFragment.java index ef680ff2..27c8a579 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/GenerateReviewFragment.java +++ b/app/src/main/java/com/m2049r/xmrwallet/GenerateReviewFragment.java @@ -27,6 +27,7 @@ import android.view.ViewGroup; import android.widget.Button; import android.widget.ProgressBar; import android.widget.TextView; +import android.widget.Toast; import com.m2049r.xmrwallet.model.Wallet; import com.m2049r.xmrwallet.model.WalletManager; @@ -66,6 +67,20 @@ public class GenerateReviewFragment extends Fragment { boolean testnet = WalletManager.getInstance().isTestNet(); tvWalletMnemonic.setTextIsSelectable(testnet); tvWalletSpendKey.setTextIsSelectable(testnet); + if (!testnet) { + tvWalletMnemonic.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Toast.makeText(getActivity(), getString(R.string.message_noselect_seed), Toast.LENGTH_SHORT).show(); + } + }); + tvWalletSpendKey.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Toast.makeText(getActivity(), getString(R.string.message_noselect_key), Toast.LENGTH_SHORT).show(); + } + }); + } bAccept.setOnClickListener(new View.OnClickListener() { @Override diff --git a/app/src/main/java/com/m2049r/xmrwallet/LoginActivity.java b/app/src/main/java/com/m2049r/xmrwallet/LoginActivity.java index e3d740ef..3d3aea8b 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/LoginActivity.java +++ b/app/src/main/java/com/m2049r/xmrwallet/LoginActivity.java @@ -45,15 +45,14 @@ import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; -import com.m2049r.xmrwallet.layout.DropDownEditText; -import com.m2049r.xmrwallet.license.LicensesFragment; +import com.m2049r.xmrwallet.dialog.HelpFragment; +import com.m2049r.xmrwallet.dialog.LicensesFragment; 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.Helper; import com.m2049r.xmrwallet.util.MoneroThreadPoolExecutor; -import com.m2049r.xmrwallet.util.NodeList; import java.io.File; import java.io.FileInputStream; @@ -971,6 +970,9 @@ 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); + return true; case R.id.action_lincense_info: LicensesFragment.displayLicensesFragment(getSupportFragmentManager()); return true; diff --git a/app/src/main/java/com/m2049r/xmrwallet/dialog/HelpFragment.java b/app/src/main/java/com/m2049r/xmrwallet/dialog/HelpFragment.java new file mode 100644 index 00000000..72751f89 --- /dev/null +++ b/app/src/main/java/com/m2049r/xmrwallet/dialog/HelpFragment.java @@ -0,0 +1,160 @@ +/** + * Copyright 2013 Adam Speakman, 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.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.view.LayoutInflater; +import android.view.View; +import android.webkit.WebView; +import android.widget.ProgressBar; + +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 { + private static final String FRAGMENT_TAG = "com.m2049r.xmrwallet.dialog.HelpFragment"; + private static final String HELP_ID = "HELP_ID"; + + private AsyncTask 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); + if (prev != null) { + ft.remove(prev); + } + ft.addToBackStack(null); + + // Create and show the dialog. + DialogFragment newFragment = HelpFragment.newInstance(helpResourceId); + newFragment.show(ft, FRAGMENT_TAG); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + 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.help_fragment, null); + webView = (WebView) content.findViewById(R.id.helpFragmentWebView); + progress = (ProgressBar) content.findViewById(R.id.helpFragmentProgress); + + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + + 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 loadHelp(final int helpResourceId) { + // Load asynchronously in case of a very large file. + loader = new AsyncTask() { + + @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 e) { + // TODO You may want to include some logging here. + } + + 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(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/m2049r/xmrwallet/license/LicensesFragment.java b/app/src/main/java/com/m2049r/xmrwallet/dialog/LicensesFragment.java similarity index 69% rename from app/src/main/java/com/m2049r/xmrwallet/license/LicensesFragment.java rename to app/src/main/java/com/m2049r/xmrwallet/dialog/LicensesFragment.java index c74449f7..f9c0794a 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/license/LicensesFragment.java +++ b/app/src/main/java/com/m2049r/xmrwallet/dialog/LicensesFragment.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.m2049r.xmrwallet.license; +package com.m2049r.xmrwallet.dialog; import java.io.BufferedReader; import java.io.IOException; @@ -51,8 +51,7 @@ public class LicensesFragment extends DialogFragment { private AsyncTask mLicenseLoader; - private static final String FRAGMENT_TAG = "nz.net.speakman.androidlicensespage.LicensesFragment"; - private static final String KEY_SHOW_CLOSE_BUTTON = "keyShowCloseButton"; + private static final String FRAGMENT_TAG = "com.m2049r.xmrwalelt.dialog.LicensesFragment"; /** * Creates a new instance of LicensesFragment with no Close button. @@ -63,22 +62,6 @@ public class LicensesFragment extends DialogFragment { return new LicensesFragment(); } - /** - * Creates a new instance of LicensesFragment with an optional Close button. - * - * @param showCloseButton Whether to show a Close button at the bottom of the dialog. - * @return A new licenses fragment. - */ - public static LicensesFragment newInstance(boolean showCloseButton) { - LicensesFragment fragment = new LicensesFragment(); - - Bundle bundle = new Bundle(); - bundle.putBoolean(KEY_SHOW_CLOSE_BUTTON, showCloseButton); - fragment.setArguments(bundle); - - return fragment; - } - /** * Builds and displays a licenses fragment with no Close button. Requires * "/res/raw/licenses.html" and "/res/layout/licenses_fragment.xml" to be @@ -99,27 +82,6 @@ public class LicensesFragment extends DialogFragment { newFragment.show(ft, FRAGMENT_TAG); } - /** - * Builds and displays a licenses fragment with or without a 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. - * @param showCloseButton Whether to show a Close button at the bottom of the dialog. - */ - public static void displayLicensesFragment(FragmentManager fm, boolean showCloseButton) { - 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(showCloseButton); - newFragment.show(ft, FRAGMENT_TAG); - } - @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); @@ -144,26 +106,18 @@ public class LicensesFragment extends DialogFragment { mWebView = (WebView) content.findViewById(R.id.licensesFragmentWebView); mIndeterminateProgress = (ProgressBar) content.findViewById(R.id.licensesFragmentIndeterminateProgress); - boolean showCloseButton = true; - Bundle arguments = getArguments(); - if (arguments != null) { - showCloseButton = arguments.getBoolean(KEY_SHOW_CLOSE_BUTTON); - } - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - TextView text = (TextView) content.findViewById(R.id.text); + TextView text = (TextView) content.findViewById(R.id.licensesFragmentText); text.setText(getString(R.string.about_text, versionName, versionCode)); builder.setView(content); - if (showCloseButton) { - builder.setNegativeButton(R.string.about_close, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int id) { - dialog.dismiss(); - } - }); - } + builder.setNegativeButton(R.string.about_close, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int id) { + dialog.dismiss(); + } + }); return builder.create(); } diff --git a/app/src/main/res/drawable/ic_help_black_24dp.xml b/app/src/main/res/drawable/ic_help_black_24dp.xml new file mode 100644 index 00000000..1517747d --- /dev/null +++ b/app/src/main/res/drawable/ic_help_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/help_fragment.xml b/app/src/main/res/layout/help_fragment.xml new file mode 100644 index 00000000..2b76cad2 --- /dev/null +++ b/app/src/main/res/layout/help_fragment.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/licenses_fragment.xml b/app/src/main/res/layout/licenses_fragment.xml index 7ce76af9..21cd690b 100644 --- a/app/src/main/res/layout/licenses_fragment.xml +++ b/app/src/main/res/layout/licenses_fragment.xml @@ -6,18 +6,18 @@ android:orientation="vertical"> @@ -25,7 +25,7 @@ android:id="@+id/licensesFragmentWebView" android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_below="@+id/text" + android:layout_below="@+id/licensesFragmentText" android:visibility="invisible" /> +

+ + + + \ No newline at end of file diff --git a/app/src/main/res/raw/help_create.html b/app/src/main/res/raw/help_create.html new file mode 100644 index 00000000..bfb30397 --- /dev/null +++ b/app/src/main/res/raw/help_create.html @@ -0,0 +1,38 @@ + + + + + +

Create Wallet

+A wallet can be created in a number of ways: + +In all cases you need to name your wallet and give it a password. The password is used for +securing your wallet data on the device. Use a strong password - better a passphrase. + +

New Address

+You need a new Monero Address.
+No need to enter additional info. + +

Recover from Seed

+You already have a Monero Address and want to recover the transactions from the blockchain.
+Enter your Seed in the field "Mnemonic Seed". If you know the block number of the first +transaction used for this address, enter it in the field "Restore Height" - leaving in blank will +scan the entire blockchain for transactions belonging to your address. +This takes a long time. + +

Recover from Keys

+Instead of recovering from the mnemonic seed, you can recover using your keys.
+Enter your Monero Address in the field "Public Address" and fill out "View Key", "Spend Key" +and optionally "Restore Height" with the appropriate values. + +

View Only

+You just want to monitor incoming transactions to a wallet.
+Enter your Monero Address in the field "Public Address" and fill out the "View Key" and +optionally "Restore Height" with the appropriate values leaving the "Spend Key" blank. + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 78b3038e..b3937cdf 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -6,6 +6,7 @@ Testnet About … + Help Details QR Receive Rename @@ -82,6 +83,9 @@ We really need those External Storage permissions! No camera = No QR scanning! + Selecting seed disabled for security reasons! + Selecting spend key disabled for security reasons! + Create Wallet Wallet Name Wallet Password