From c39a4bbea6d6618c75102688463b597b4af83840 Mon Sep 17 00:00:00 2001 From: Jakob Nixdorf Date: Wed, 6 Dec 2017 11:11:41 +0100 Subject: [PATCH] Refactor complex dialogs in separate classes * Create the ManualEntryDialog class * Move the TagDialogHelper to TagsDialog --- .../andotp/Activities/MainActivity.java | 129 +------------- .../andotp/View/EntriesCardAdapter.java | 3 +- .../flocke/andotp/View/ManualEntryDialog.java | 161 ++++++++++++++++++ .../TagsDialog.java} | 7 +- 4 files changed, 168 insertions(+), 132 deletions(-) create mode 100644 app/src/main/java/org/shadowice/flocke/andotp/View/ManualEntryDialog.java rename app/src/main/java/org/shadowice/flocke/andotp/{Utilities/TagDialogHelper.java => View/TagsDialog.java} (95%) diff --git a/app/src/main/java/org/shadowice/flocke/andotp/Activities/MainActivity.java b/app/src/main/java/org/shadowice/flocke/andotp/Activities/MainActivity.java index b4b9c58e..6cffff8a 100644 --- a/app/src/main/java/org/shadowice/flocke/andotp/Activities/MainActivity.java +++ b/app/src/main/java/org/shadowice/flocke/andotp/Activities/MainActivity.java @@ -48,13 +48,9 @@ import android.view.ViewGroup; import android.view.WindowManager; import android.view.animation.LinearInterpolator; import android.widget.AdapterView; -import android.widget.ArrayAdapter; -import android.widget.Button; import android.widget.CheckedTextView; -import android.widget.EditText; import android.widget.ListView; import android.widget.ProgressBar; -import android.widget.Spinner; import android.widget.Toast; import com.google.zxing.integration.android.IntentIntegrator; @@ -64,18 +60,15 @@ import org.shadowice.flocke.andotp.Database.Entry; import org.shadowice.flocke.andotp.R; import org.shadowice.flocke.andotp.Utilities.DatabaseHelper; import org.shadowice.flocke.andotp.Utilities.Settings; -import org.shadowice.flocke.andotp.Utilities.TagDialogHelper; import org.shadowice.flocke.andotp.Utilities.TokenCalculator; import org.shadowice.flocke.andotp.View.EntriesCardAdapter; import org.shadowice.flocke.andotp.View.FloatingActionMenu; import org.shadowice.flocke.andotp.View.ItemTouchHelper.SimpleItemTouchHelperCallback; +import org.shadowice.flocke.andotp.View.ManualEntryDialog; import org.shadowice.flocke.andotp.View.TagsAdapter; import java.util.ArrayList; import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.concurrent.Callable; import static org.shadowice.flocke.andotp.Utilities.Settings.SortMode; @@ -108,122 +101,6 @@ public class MainActivity extends BaseActivity .initiateScan(); } - // Manual data entry - private void enterDetails() { - ViewGroup container = findViewById(R.id.main_content); - View inputView = getLayoutInflater().inflate(R.layout.dialog_manual_entry, container, false); - - final Spinner typeInput = inputView.findViewById(R.id.manual_type); - final EditText labelInput = inputView.findViewById(R.id.manual_label); - final EditText secretInput = inputView.findViewById(R.id.manual_secret); - final EditText periodInput = inputView.findViewById(R.id.manual_period); - final EditText digitsInput = inputView.findViewById(R.id.manual_digits); - final Spinner algorithmInput = inputView.findViewById(R.id.manual_algorithm); - final Button tagsInput = inputView.findViewById(R.id.manual_tags); - - final ArrayAdapter algorithmAdapter = new ArrayAdapter<>(this, android.R.layout.simple_expandable_list_item_1, TokenCalculator.HashAlgorithm.values()); - final ArrayAdapter typeAdapter = new ArrayAdapter<>(this, android.R.layout.simple_expandable_list_item_1, Entry.PublicTypes.toArray(new Entry.OTPType[Entry.PublicTypes.size()])); - final ArrayAdapter fullTypeAdapter = new ArrayAdapter<>(this, android.R.layout.simple_expandable_list_item_1, Entry.OTPType.values()); - - if (settings.getSpecialFeatures()) - typeInput.setAdapter(fullTypeAdapter); - else - typeInput.setAdapter(typeAdapter); - - algorithmInput.setAdapter(algorithmAdapter); - - periodInput.setText(String.format(Locale.US, "%d", TokenCalculator.TOTP_DEFAULT_PERIOD)); - digitsInput.setText(String.format(Locale.US, "%d", TokenCalculator.TOTP_DEFAULT_DIGITS)); - - typeInput.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView adapterView, View view, int i, long l) { - Entry.OTPType type = (Entry.OTPType) adapterView.getSelectedItem(); - - if (type == Entry.OTPType.STEAM) { - digitsInput.setText(String.format(Locale.US, "%d", TokenCalculator.STEAM_DEFAULT_DIGITS)); - periodInput.setText(String.format(Locale.US, "%d", TokenCalculator.TOTP_DEFAULT_PERIOD)); - algorithmInput.setSelection(algorithmAdapter.getPosition(TokenCalculator.HashAlgorithm.SHA1)); - - digitsInput.setEnabled(false); - periodInput.setEnabled(false); - algorithmInput.setEnabled(false); - } else { - digitsInput.setText(String.format(Locale.US, "%d", TokenCalculator.TOTP_DEFAULT_DIGITS)); - digitsInput.setEnabled(true); - periodInput.setEnabled(true); - algorithmInput.setEnabled(true); - } - } - - @Override - public void onNothingSelected(AdapterView adapterView) { - - } - }); - - List allTags = adapter.getTags(); - HashMap tagsHashMap = new HashMap<>(); - for(String tag: allTags) { - tagsHashMap.put(tag, false); - } - final TagsAdapter tagsAdapter = new TagsAdapter(this, tagsHashMap); - - final Callable tagsCallable = new Callable() { - @Override - public Object call() throws Exception { - List selectedTags = tagsAdapter.getActiveTags(); - StringBuilder stringBuilder = new StringBuilder(); - for(int j = 0; j < selectedTags.size(); j++) { - stringBuilder.append(selectedTags.get(j)); - if(j < selectedTags.size() - 1) { - stringBuilder.append(", "); - } - } - tagsInput.setText(stringBuilder.toString()); - return null; - } - }; - - tagsInput.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - TagDialogHelper.createTagsDialog(MainActivity.this, tagsAdapter, tagsCallable, tagsCallable); - } - }); - - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setTitle(R.string.dialog_title_manual_entry) - .setView(inputView) - .setPositiveButton(R.string.button_save, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - Entry.OTPType type = (Entry.OTPType) typeInput.getSelectedItem(); - TokenCalculator.HashAlgorithm algorithm = (TokenCalculator.HashAlgorithm) algorithmInput.getSelectedItem(); - - if (type == Entry.OTPType.TOTP || type == Entry.OTPType.STEAM) { - String label = labelInput.getText().toString(); - String secret = secretInput.getText().toString(); - int period = Integer.parseInt(periodInput.getText().toString()); - int digits = Integer.parseInt(digitsInput.getText().toString()); - - Entry e = new Entry(type, secret, period, digits, label, algorithm, tagsAdapter.getActiveTags()); - e.updateOTP(); - adapter.addEntry(e); - adapter.saveEntries(); - - refreshTags(); - } - } - }) - .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) {} - }) - .create() - .show(); - } - private void showFirstTimeWarning() { ViewGroup container = findViewById(R.id.main_content); View msgView = getLayoutInflater().inflate(R.layout.dialog_security_backup, container, false); @@ -314,7 +191,7 @@ public class MainActivity extends BaseActivity @Override public void onManualFabClick() { - enterDetails(); + ManualEntryDialog.show(MainActivity.this, settings, adapter); } }); @@ -707,7 +584,7 @@ public class MainActivity extends BaseActivity adapter.filterByTags(tagsDrawerAdapter.getActiveTags()); } - void refreshTags() { + public void refreshTags() { HashMap tagsHashMap = new HashMap<>(); for(String tag: tagsDrawerAdapter.getTags()) { tagsHashMap.put(tag, false); diff --git a/app/src/main/java/org/shadowice/flocke/andotp/View/EntriesCardAdapter.java b/app/src/main/java/org/shadowice/flocke/andotp/View/EntriesCardAdapter.java index 396ebc82..8a42d1a9 100644 --- a/app/src/main/java/org/shadowice/flocke/andotp/View/EntriesCardAdapter.java +++ b/app/src/main/java/org/shadowice/flocke/andotp/View/EntriesCardAdapter.java @@ -51,7 +51,6 @@ import org.shadowice.flocke.andotp.R; import org.shadowice.flocke.andotp.Utilities.DatabaseHelper; import org.shadowice.flocke.andotp.Utilities.EntryThumbnail; import org.shadowice.flocke.andotp.Utilities.Settings; -import org.shadowice.flocke.andotp.Utilities.TagDialogHelper; import org.shadowice.flocke.andotp.View.ItemTouchHelper.ItemTouchHelperAdapter; import java.text.Collator; @@ -449,7 +448,7 @@ public class EntriesCardAdapter extends RecyclerView.Adapter } }; - TagDialogHelper.createTagsDialog(context, tagsAdapter, tagsCallable, tagsCallable); + TagsDialog.show(context, tagsAdapter, tagsCallable, tagsCallable); } public void removeItem(final int pos) { diff --git a/app/src/main/java/org/shadowice/flocke/andotp/View/ManualEntryDialog.java b/app/src/main/java/org/shadowice/flocke/andotp/View/ManualEntryDialog.java new file mode 100644 index 00000000..3d87bfbc --- /dev/null +++ b/app/src/main/java/org/shadowice/flocke/andotp/View/ManualEntryDialog.java @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2017 Jakob Nixdorf + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.shadowice.flocke.andotp.View; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Spinner; + +import org.shadowice.flocke.andotp.Activities.MainActivity; +import org.shadowice.flocke.andotp.Database.Entry; +import org.shadowice.flocke.andotp.R; +import org.shadowice.flocke.andotp.Utilities.Settings; +import org.shadowice.flocke.andotp.Utilities.TokenCalculator; + +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.concurrent.Callable; + +public class ManualEntryDialog { + public static void show(final MainActivity callingActivity, Settings settings, final EntriesCardAdapter adapter) { + ViewGroup container = callingActivity.findViewById(R.id.main_content); + View inputView = callingActivity.getLayoutInflater().inflate(R.layout.dialog_manual_entry, container, false); + + final Spinner typeInput = inputView.findViewById(R.id.manual_type); + final EditText labelInput = inputView.findViewById(R.id.manual_label); + final EditText secretInput = inputView.findViewById(R.id.manual_secret); + final EditText periodInput = inputView.findViewById(R.id.manual_period); + final EditText digitsInput = inputView.findViewById(R.id.manual_digits); + final Spinner algorithmInput = inputView.findViewById(R.id.manual_algorithm); + final Button tagsInput = inputView.findViewById(R.id.manual_tags); + + final ArrayAdapter algorithmAdapter = new ArrayAdapter<>(callingActivity, android.R.layout.simple_expandable_list_item_1, TokenCalculator.HashAlgorithm.values()); + final ArrayAdapter typeAdapter = new ArrayAdapter<>(callingActivity, android.R.layout.simple_expandable_list_item_1, Entry.PublicTypes.toArray(new Entry.OTPType[Entry.PublicTypes.size()])); + final ArrayAdapter fullTypeAdapter = new ArrayAdapter<>(callingActivity, android.R.layout.simple_expandable_list_item_1, Entry.OTPType.values()); + + if (settings.getSpecialFeatures()) + typeInput.setAdapter(fullTypeAdapter); + else + typeInput.setAdapter(typeAdapter); + + algorithmInput.setAdapter(algorithmAdapter); + + periodInput.setText(String.format(Locale.US, "%d", TokenCalculator.TOTP_DEFAULT_PERIOD)); + digitsInput.setText(String.format(Locale.US, "%d", TokenCalculator.TOTP_DEFAULT_DIGITS)); + + typeInput.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView adapterView, View view, int i, long l) { + Entry.OTPType type = (Entry.OTPType) adapterView.getSelectedItem(); + + if (type == Entry.OTPType.STEAM) { + digitsInput.setText(String.format(Locale.US, "%d", TokenCalculator.STEAM_DEFAULT_DIGITS)); + periodInput.setText(String.format(Locale.US, "%d", TokenCalculator.TOTP_DEFAULT_PERIOD)); + algorithmInput.setSelection(algorithmAdapter.getPosition(TokenCalculator.HashAlgorithm.SHA1)); + + digitsInput.setEnabled(false); + periodInput.setEnabled(false); + algorithmInput.setEnabled(false); + } else { + digitsInput.setText(String.format(Locale.US, "%d", TokenCalculator.TOTP_DEFAULT_DIGITS)); + digitsInput.setEnabled(true); + periodInput.setEnabled(true); + algorithmInput.setEnabled(true); + } + } + + @Override + public void onNothingSelected(AdapterView adapterView) { + + } + }); + + List allTags = adapter.getTags(); + HashMap tagsHashMap = new HashMap<>(); + for(String tag: allTags) { + tagsHashMap.put(tag, false); + } + final TagsAdapter tagsAdapter = new TagsAdapter(callingActivity, tagsHashMap); + + final Callable tagsCallable = new Callable() { + @Override + public Object call() throws Exception { + List selectedTags = tagsAdapter.getActiveTags(); + StringBuilder stringBuilder = new StringBuilder(); + for(int j = 0; j < selectedTags.size(); j++) { + stringBuilder.append(selectedTags.get(j)); + if(j < selectedTags.size() - 1) { + stringBuilder.append(", "); + } + } + tagsInput.setText(stringBuilder.toString()); + return null; + } + }; + + tagsInput.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + TagsDialog.show(callingActivity, tagsAdapter, tagsCallable, tagsCallable); + } + }); + + AlertDialog.Builder builder = new AlertDialog.Builder(callingActivity); + builder.setTitle(R.string.dialog_title_manual_entry) + .setView(inputView) + .setPositiveButton(R.string.button_save, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + Entry.OTPType type = (Entry.OTPType) typeInput.getSelectedItem(); + TokenCalculator.HashAlgorithm algorithm = (TokenCalculator.HashAlgorithm) algorithmInput.getSelectedItem(); + + if (type == Entry.OTPType.TOTP || type == Entry.OTPType.STEAM) { + String label = labelInput.getText().toString(); + String secret = secretInput.getText().toString(); + int period = Integer.parseInt(periodInput.getText().toString()); + int digits = Integer.parseInt(digitsInput.getText().toString()); + + Entry e = new Entry(type, secret, period, digits, label, algorithm, tagsAdapter.getActiveTags()); + e.updateOTP(); + adapter.addEntry(e); + adapter.saveEntries(); + + callingActivity.refreshTags(); + } + } + }) + .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) {} + }) + .create() + .show(); + } +} diff --git a/app/src/main/java/org/shadowice/flocke/andotp/Utilities/TagDialogHelper.java b/app/src/main/java/org/shadowice/flocke/andotp/View/TagsDialog.java similarity index 95% rename from app/src/main/java/org/shadowice/flocke/andotp/Utilities/TagDialogHelper.java rename to app/src/main/java/org/shadowice/flocke/andotp/View/TagsDialog.java index 7a6c96fe..03ed43c9 100644 --- a/app/src/main/java/org/shadowice/flocke/andotp/Utilities/TagDialogHelper.java +++ b/app/src/main/java/org/shadowice/flocke/andotp/View/TagsDialog.java @@ -21,7 +21,7 @@ * SOFTWARE. */ -package org.shadowice.flocke.andotp.Utilities; +package org.shadowice.flocke.andotp.View; import android.app.AlertDialog; import android.content.Context; @@ -35,13 +35,12 @@ import android.widget.FrameLayout; import android.widget.ListView; import org.shadowice.flocke.andotp.R; -import org.shadowice.flocke.andotp.View.TagsAdapter; import java.util.HashMap; import java.util.concurrent.Callable; -public class TagDialogHelper { - public static void createTagsDialog(Context context, final TagsAdapter tagsAdapter, final Callable newTagCallable, final Callable selectedTagsCallable) { +public class TagsDialog { + public static void show(Context context, final TagsAdapter tagsAdapter, final Callable newTagCallable, final Callable selectedTagsCallable) { int margin = context.getResources().getDimensionPixelSize(R.dimen.activity_margin); int marginSmall = context.getResources().getDimensionPixelSize(R.dimen.activity_margin_small); int marginMedium = context.getResources().getDimensionPixelSize(R.dimen.activity_margin_medium);