From 1b41abdb385e7f6b043af4effaa97615e74f8ede Mon Sep 17 00:00:00 2001 From: Peter Olamit Date: Mon, 6 May 2019 12:28:57 -0700 Subject: [PATCH 1/8] initial-gql-integration --- .../ui/repository/TransferMethodConfigurationRepository.java | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/src/main/java/com/hyperwallet/android/ui/repository/TransferMethodConfigurationRepository.java b/ui/src/main/java/com/hyperwallet/android/ui/repository/TransferMethodConfigurationRepository.java index e89c8bab5..49bfc8b75 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/repository/TransferMethodConfigurationRepository.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/repository/TransferMethodConfigurationRepository.java @@ -36,6 +36,7 @@ public interface TransferMethodConfigurationRepository { + //TODO update GQL integration development feature void getKeys(@NonNull final LoadKeysCallback loadKeysCallback); void getFields(@NonNull final String country, @NonNull final String currency, From f41207cbc19f931d7da3fc8b21e8428957f69a7d Mon Sep 17 00:00:00 2001 From: Peter Joseph Olamit Date: Tue, 21 May 2019 15:40:54 -0700 Subject: [PATCH 2/8] HW-52170 key and field gql integration (#19) --- build.gradle | 2 +- ui/build.gradle | 4 +- ...TransferMethodConfigurationRepository.java | 15 +- ...sferMethodConfigurationRepositoryImpl.java | 73 +++-- .../repository/TransferMethodRepository.java | 4 +- .../TransferMethodRepositoryImpl.java | 2 +- .../AddTransferMethodContract.java | 8 +- .../AddTransferMethodFragment.java | 109 ++++--- .../AddTransferMethodPresenter.java | 19 +- .../ui/transfermethod/FeeFormatter.java | 34 +- .../ListTransferMethodPresenter.java | 2 +- .../SelectTransferMethodFragment.java | 6 +- .../SelectTransferMethodPresenter.java | 116 +++---- .../TransferMethodSelectionItem.java | 19 +- .../view/WidgetSelectionDialogFragment.java | 92 +++++- .../ui/view/widget/AbstractWidget.java | 38 +-- .../android/ui/view/widget/DateWidget.java | 29 +- .../ui/view/widget/DefaultAccountWidget.java | 23 +- .../ui/view/widget/ExpiryDateWidget.java | 43 ++- .../android/ui/view/widget/NumberWidget.java | 29 +- .../android/ui/view/widget/PhoneWidget.java | 28 +- .../ui/view/widget/SelectionWidget.java | 63 ++-- .../android/ui/view/widget/TextWidget.java | 31 +- .../android/ui/view/widget/WidgetFactory.java | 15 +- .../layout/fragment_add_transfer_method.xml | 15 - ui/src/main/res/layout/item_widget_layout.xml | 10 + .../res/layout/item_widget_section_header.xml | 15 + .../main/res/menu/menu_widget_selection.xml | 10 + ui/src/main/res/values/dimens.xml | 4 + ui/src/main/res/values/ids.xml | 39 +++ ui/src/main/res/values/strings.xml | 8 + ui/src/main/res/values/styles.xml | 11 + ...MethodConfigurationRepositoryImplTest.java | 83 ++--- .../TransferMethodRepositoryImplTest.java | 6 +- .../ui/repository/UserRepositoryImplTest.java | 1 - .../AddTransferMethodPresenterTest.java | 37 ++- .../ui/transfermethod/FeeFormatterTest.java | 70 +++-- .../ListTransferMethodPresenterTest.java | 20 +- .../SelectTransferMethodPresenterTest.java | 21 +- .../add_transfer_method_presenter_test.json | 37 ++- ui/src/test/resources/fee_information.json | 77 +++++ ...ful_tmc_fields_empty_details_response.json | 134 ++++---- .../successful_tmc_fields_response.json | 149 ++++----- .../successful_tmc_keys_response.json | 292 ++++++++---------- 44 files changed, 1072 insertions(+), 771 deletions(-) create mode 100644 ui/src/main/res/layout/item_widget_layout.xml create mode 100644 ui/src/main/res/layout/item_widget_section_header.xml create mode 100644 ui/src/main/res/menu/menu_widget_selection.xml create mode 100644 ui/src/test/resources/fee_information.json diff --git a/build.gradle b/build.gradle index aa5a21068..b079d8d65 100644 --- a/build.gradle +++ b/build.gradle @@ -24,7 +24,7 @@ allprojects { } - project.version = "1.0.0-beta02"; + project.version = "1.0.0-beta03-SNAPSHOT" } task clean(type: Delete) { diff --git a/ui/build.gradle b/ui/build.gradle index 36be7e3cb..36e57ea3a 100644 --- a/ui/build.gradle +++ b/ui/build.gradle @@ -49,7 +49,7 @@ dependencies { implementation "androidx.legacy:legacy-support-v4:1.0.0" implementation "androidx.recyclerview:recyclerview:1.0.0" - api 'com.hyperwallet.android:core-sdk:1.0.0-beta02' + api "com.hyperwallet.android:core-sdk:1.0.0-beta03-SNAPSHOT" androidTestImplementation "androidx.test.ext:junit:1.1.0" androidTestImplementation "androidx.test:runner:1.1.1" @@ -61,7 +61,7 @@ dependencies { androidTestImplementation "com.squareup.leakcanary:leakcanary-android-instrumentation:1.6.3" androidTestImplementation "com.squareup.leakcanary:leakcanary-support-fragment:1.6.3" - testImplementation group: 'org.mockito', name: 'mockito-core', version: "2.23.4" + testImplementation group: 'org.mockito', name: 'mockito-core', version: "2.25.0" testImplementation group: 'pl.pragmatists', name: 'JUnitParams', version: "1.1.1" testImplementation "org.robolectric:robolectric:4.1" testImplementation "com.squareup.okhttp3:mockwebserver:3.11.0" diff --git a/ui/src/main/java/com/hyperwallet/android/ui/repository/TransferMethodConfigurationRepository.java b/ui/src/main/java/com/hyperwallet/android/ui/repository/TransferMethodConfigurationRepository.java index 28d96f19e..a937b371e 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/repository/TransferMethodConfigurationRepository.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/repository/TransferMethodConfigurationRepository.java @@ -24,19 +24,17 @@ * USE OR OTHER DEALINGS * IN THE SOFTWARE. */ - package com.hyperwallet.android.ui.repository; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.hyperwallet.android.model.HyperwalletErrors; -import com.hyperwallet.android.model.meta.HyperwalletTransferMethodConfigurationFieldResult; -import com.hyperwallet.android.model.meta.HyperwalletTransferMethodConfigurationKeyResult; +import com.hyperwallet.android.model.meta.HyperwalletTransferMethodConfigurationField; +import com.hyperwallet.android.model.meta.HyperwalletTransferMethodConfigurationKey; public interface TransferMethodConfigurationRepository { - //TODO update GQL integration development feature void getKeys(@NonNull final LoadKeysCallback loadKeysCallback); void getFields(@NonNull final String country, @NonNull final String currency, @@ -48,15 +46,16 @@ void getFields(@NonNull final String country, @NonNull final String currency, void refreshFields(); interface LoadKeysCallback { - void onKeysLoaded( - @Nullable final HyperwalletTransferMethodConfigurationKeyResult transferMethodConfigurationKeyResult); + + void onKeysLoaded(@Nullable final HyperwalletTransferMethodConfigurationKey transferMethodConfigurationKey); void onError(@NonNull final HyperwalletErrors errors); } interface LoadFieldsCallback { - void onFieldsLoaded(@Nullable final HyperwalletTransferMethodConfigurationFieldResult - transferMethodConfigurationFieldResult); + + void onFieldsLoaded(@Nullable final HyperwalletTransferMethodConfigurationField field, + @Nullable final String processingTime); void onError(@NonNull final HyperwalletErrors errors); } diff --git a/ui/src/main/java/com/hyperwallet/android/ui/repository/TransferMethodConfigurationRepositoryImpl.java b/ui/src/main/java/com/hyperwallet/android/ui/repository/TransferMethodConfigurationRepositoryImpl.java index 89aa23f59..67f2c2278 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/repository/TransferMethodConfigurationRepositoryImpl.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/repository/TransferMethodConfigurationRepositoryImpl.java @@ -24,7 +24,6 @@ * USE OR OTHER DEALINGS * IN THE SOFTWARE. */ - package com.hyperwallet.android.ui.repository; import android.os.Handler; @@ -36,8 +35,9 @@ import com.hyperwallet.android.Hyperwallet; import com.hyperwallet.android.exception.HyperwalletException; import com.hyperwallet.android.listener.HyperwalletListener; -import com.hyperwallet.android.model.meta.HyperwalletTransferMethodConfigurationFieldResult; -import com.hyperwallet.android.model.meta.HyperwalletTransferMethodConfigurationKeyResult; +import com.hyperwallet.android.model.meta.HyperwalletTransferMethodConfigurationField; +import com.hyperwallet.android.model.meta.HyperwalletTransferMethodConfigurationKey; +import com.hyperwallet.android.model.meta.keyed.HyperwalletTransferMethodType; import com.hyperwallet.android.model.meta.query.HyperwalletTransferMethodConfigurationFieldQuery; import com.hyperwallet.android.model.meta.query.HyperwalletTransferMethodConfigurationKeysQuery; import com.hyperwallet.android.ui.util.EspressoIdlingResource; @@ -45,11 +45,12 @@ import java.util.HashMap; import java.util.Map; import java.util.Objects; +import java.util.Set; public class TransferMethodConfigurationRepositoryImpl implements TransferMethodConfigurationRepository { - private HyperwalletTransferMethodConfigurationKeyResult mTransferMethodConfigurationKeyResult; + private HyperwalletTransferMethodConfigurationKey mTransferMethodConfigurationKey; private final Handler mHandler; - private final Map mFieldMap; + private final Map mFieldMap; TransferMethodConfigurationRepositoryImpl() { mHandler = new Handler(); @@ -63,11 +64,10 @@ Hyperwallet getHyperwallet() { @VisibleForTesting() protected TransferMethodConfigurationRepositoryImpl(@Nullable Handler handler, - HyperwalletTransferMethodConfigurationKeyResult - transferMethodConfigurationKeyResult, Map fieldMap) { + HyperwalletTransferMethodConfigurationKey transferMethodConfigurationKey, + Map fieldMap) { mHandler = handler; - mTransferMethodConfigurationKeyResult = transferMethodConfigurationKeyResult; + mTransferMethodConfigurationKey = transferMethodConfigurationKey; mFieldMap = fieldMap; } @@ -77,11 +77,11 @@ void getTransferMethodConfigurationKeyResult(final LoadKeysCallback loadKeysCall EspressoIdlingResource.increment(); getHyperwallet().retrieveTransferMethodConfigurationKeys(query, - new HyperwalletListener() { + new HyperwalletListener() { @Override - public void onSuccess(@Nullable HyperwalletTransferMethodConfigurationKeyResult result) { - mTransferMethodConfigurationKeyResult = result; - loadKeysCallback.onKeysLoaded(mTransferMethodConfigurationKeyResult); + public void onSuccess(@Nullable HyperwalletTransferMethodConfigurationKey result) { + mTransferMethodConfigurationKey = result; + loadKeysCallback.onKeysLoaded(mTransferMethodConfigurationKey); EspressoIdlingResource.decrement(); } @@ -106,18 +106,19 @@ void getTransferMethodConfigurationFieldResult(@NonNull final String country, @NonNull final String transferMethodProfileType, @NonNull final LoadFieldsCallback loadFieldsCallback) { HyperwalletTransferMethodConfigurationFieldQuery query = - new HyperwalletTransferMethodConfigurationFieldQuery(country, currency, transferMethodType, - transferMethodProfileType); + new HyperwalletTransferMethodConfigurationFieldQuery(country, currency, + transferMethodType, transferMethodProfileType); EspressoIdlingResource.increment(); getHyperwallet().retrieveTransferMethodConfigurationFields( query, - new HyperwalletListener() { + new HyperwalletListener() { @Override - public void onSuccess(HyperwalletTransferMethodConfigurationFieldResult result) { + public void onSuccess(HyperwalletTransferMethodConfigurationField result) { FieldMapKey fieldMapKey = new FieldMapKey(country, currency, transferMethodType); mFieldMap.put(fieldMapKey, result); - loadFieldsCallback.onFieldsLoaded(result); + loadFieldsCallback.onFieldsLoaded(result, + getProcessingTime(country, currency, transferMethodType)); EspressoIdlingResource.decrement(); } @@ -137,10 +138,10 @@ public Handler getHandler() { @Override public synchronized void getKeys(@NonNull final LoadKeysCallback loadKeysCallback) { - if (mTransferMethodConfigurationKeyResult == null) { + if (mTransferMethodConfigurationKey == null) { getTransferMethodConfigurationKeyResult(loadKeysCallback); } else { - loadKeysCallback.onKeysLoaded(mTransferMethodConfigurationKeyResult); + loadKeysCallback.onKeysLoaded(mTransferMethodConfigurationKey); } } @@ -149,27 +150,45 @@ public synchronized void getFields(@NonNull final String country, @NonNull final @NonNull final String transferMethodType, @NonNull final String transferMethodProfileType, @NonNull final LoadFieldsCallback loadFieldsCallback) { + FieldMapKey fieldMapKey = new FieldMapKey(country, currency, transferMethodType); - HyperwalletTransferMethodConfigurationFieldResult transferMethodConfigurationFieldResult = mFieldMap.get( - fieldMapKey); + HyperwalletTransferMethodConfigurationField transferMethodConfigurationField = mFieldMap.get(fieldMapKey); // if there is no value for country-currency-type combination, // it means api call was never made or this combination or it was refreshed - if (transferMethodConfigurationFieldResult == null) { - getTransferMethodConfigurationFieldResult(country, currency, transferMethodType, transferMethodProfileType, loadFieldsCallback); + if (transferMethodConfigurationField == null) { + getTransferMethodConfigurationFieldResult(country, currency, transferMethodType, + transferMethodProfileType, loadFieldsCallback); } else { - loadFieldsCallback.onFieldsLoaded(transferMethodConfigurationFieldResult); + loadFieldsCallback.onFieldsLoaded(transferMethodConfigurationField, + getProcessingTime(country, currency, transferMethodType)); } } @Override public void refreshKeys() { - mTransferMethodConfigurationKeyResult = null; + mTransferMethodConfigurationKey = null; } @Override public void refreshFields() { mFieldMap.clear(); } + + //TODO this method is just temporary, placed to get the processing time + //Next iteration from API will have ProcessingTime as a separate node + @Nullable + private String getProcessingTime(String country, String currency, String transferMethodType) { + if (mTransferMethodConfigurationKey != null) { + Set transferMethodTypes = mTransferMethodConfigurationKey + .getTransferMethodType(country, currency); + for (HyperwalletTransferMethodType type : transferMethodTypes) { + if (type.getName().equals(transferMethodType)) { + return type.getProcessingTime(); + } + } + } + return null; + } } class FieldMapKey { @@ -213,6 +232,4 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(mCountry, mCurrency, mTransferMethodType); } - - } diff --git a/ui/src/main/java/com/hyperwallet/android/ui/repository/TransferMethodRepository.java b/ui/src/main/java/com/hyperwallet/android/ui/repository/TransferMethodRepository.java index 46d5ec781..de222ff69 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/repository/TransferMethodRepository.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/repository/TransferMethodRepository.java @@ -39,11 +39,11 @@ void createTransferMethod(@NonNull HyperwalletTransferMethod transferMethod, @NonNull LoadTransferMethodCallback callback); /** - * Load transfe methods available associated with current context + * Load transfer methods available associated with current context * * @param callback @see {@link LoadTransferMethodListCallback} */ - void loadTransferMethod(@NonNull LoadTransferMethodListCallback callback); + void loadTransferMethods(@NonNull LoadTransferMethodListCallback callback); /** * Deactivate transfer method specified. diff --git a/ui/src/main/java/com/hyperwallet/android/ui/repository/TransferMethodRepositoryImpl.java b/ui/src/main/java/com/hyperwallet/android/ui/repository/TransferMethodRepositoryImpl.java index 7bc72f0c9..4becad682 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/repository/TransferMethodRepositoryImpl.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/repository/TransferMethodRepositoryImpl.java @@ -65,7 +65,7 @@ public void createTransferMethod(@NonNull final HyperwalletTransferMethod transf } @Override - public void loadTransferMethod(@NonNull final LoadTransferMethodListCallback callback) { + public void loadTransferMethods(@NonNull final LoadTransferMethodListCallback callback) { getHyperwallet().listTransferMethods(null, new HyperwalletListener>() { @Override diff --git a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodContract.java b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodContract.java index 93f3aa9da..eb3e29810 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodContract.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodContract.java @@ -20,8 +20,8 @@ import com.hyperwallet.android.model.HyperwalletError; import com.hyperwallet.android.model.HyperwalletTransferMethod; -import com.hyperwallet.android.model.meta.Fee; -import com.hyperwallet.android.model.meta.HyperwalletField; +import com.hyperwallet.android.model.meta.HyperwalletFee; +import com.hyperwallet.android.model.meta.field.HyperwalletFieldGroup; import java.util.List; @@ -38,9 +38,9 @@ interface View { void showErrorLoadTransferMethodConfigurationFields(@NonNull final List errors); - void showTransferMethodFields(@NonNull final List fields); + void showTransferMethodFields(@NonNull final List fields); - void showTransactionInformation(List fees, String processingTime); + void showTransactionInformation(List fees, String processingTime); void showCreateButtonProgressBar(); diff --git a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodFragment.java b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodFragment.java index 2507c3eed..d220ba52b 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodFragment.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodFragment.java @@ -16,6 +16,7 @@ */ package com.hyperwallet.android.ui.transfermethod; +import static com.hyperwallet.android.model.HyperwalletTransferMethod.TransferMethodFields.PROFILE_TYPE; import static com.hyperwallet.android.model.HyperwalletTransferMethod.TransferMethodFields.TRANSFER_METHOD_COUNTRY; import static com.hyperwallet.android.model.HyperwalletTransferMethod.TransferMethodFields.TRANSFER_METHOD_CURRENCY; import static com.hyperwallet.android.model.HyperwalletTransferMethod.TransferMethodFields.TYPE; @@ -50,8 +51,9 @@ import com.hyperwallet.android.model.HyperwalletError; import com.hyperwallet.android.model.HyperwalletTransferMethod; import com.hyperwallet.android.model.PayPalAccount; -import com.hyperwallet.android.model.meta.Fee; -import com.hyperwallet.android.model.meta.HyperwalletField; +import com.hyperwallet.android.model.meta.HyperwalletFee; +import com.hyperwallet.android.model.meta.field.HyperwalletField; +import com.hyperwallet.android.model.meta.field.HyperwalletFieldGroup; import com.hyperwallet.android.ui.HyperwalletLocalBroadcast; import com.hyperwallet.android.ui.repository.RepositoryFactory; import com.hyperwallet.android.ui.view.WidgetSelectionDialogFragment; @@ -92,7 +94,6 @@ public class AddTransferMethodFragment extends Fragment implements WidgetEventLi private HyperwalletTransferMethod mTransferMethod; private String mTransferMethodProfileType; private HashMap mWidgetInputStateHashMap; - private TextView sectionHeaderTextView; /** * Please do not use this to have instance of AddTransferMethodFragment this is reserved for android framework @@ -176,8 +177,6 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat super.onViewCreated(view, savedInstanceState); mDynamicContainer = view.findViewById(R.id.add_transfer_method_dynamic_container); - sectionHeaderTextView = view.findViewById(R.id.account_information_section_header); - mCreateButtonProgressBar = view.findViewById(R.id.add_transfer_method_create_button_progress_bar); mProgressBar = view.findViewById(R.id.add_transfer_method_progress_bar_layout); @@ -211,6 +210,7 @@ public void onViewStateRestored(@Nullable Bundle savedInstanceState) { mCountry = savedInstanceState.getString(ARGUMENT_TRANSFER_METHOD_COUNTRY); mCurrency = savedInstanceState.getString(ARGUMENT_TRANSFER_METHOD_CURRENCY); mTransferMethodType = savedInstanceState.getString(ARGUMENT_TRANSFER_METHOD_TYPE); + mTransferMethodProfileType = savedInstanceState.getString(ARGUMENT_TRANSFER_METHOD_PROFILE_TYPE); mShowCreateProgressBar = savedInstanceState.getBoolean(ARGUMENT_SHOW_CREATE_PROGRESS_BAR); mTransferMethod = savedInstanceState.getParcelable(ARGUMENT_TRANSFER_METHOD); } else { // same as AddTransferMethodFragment#newInstance @@ -218,12 +218,9 @@ public void onViewStateRestored(@Nullable Bundle savedInstanceState) { mCountry = getArguments().getString(ARGUMENT_TRANSFER_METHOD_COUNTRY); mCurrency = getArguments().getString(ARGUMENT_TRANSFER_METHOD_CURRENCY); mTransferMethodType = getArguments().getString(ARGUMENT_TRANSFER_METHOD_TYPE); + mTransferMethodProfileType = getArguments().getString(ARGUMENT_TRANSFER_METHOD_PROFILE_TYPE); mTransferMethod = getArguments().getParcelable(ARGUMENT_TRANSFER_METHOD); } - - Locale locale = new Locale.Builder().setRegion(mCountry).build(); - sectionHeaderTextView.setText(requireContext().getResources() - .getString(R.string.account_information_section_header, locale.getDisplayName(), mCurrency)); } @Override @@ -244,6 +241,7 @@ public void onSaveInstanceState(@NonNull Bundle outState) { outState.putString(ARGUMENT_TRANSFER_METHOD_COUNTRY, mCountry); outState.putString(ARGUMENT_TRANSFER_METHOD_CURRENCY, mCurrency); outState.putString(ARGUMENT_TRANSFER_METHOD_TYPE, mTransferMethodType); + outState.putString(ARGUMENT_TRANSFER_METHOD_PROFILE_TYPE, mTransferMethodProfileType); outState.putBoolean(ARGUMENT_SHOW_CREATE_PROGRESS_BAR, mShowCreateProgressBar); outState.putParcelable(ARGUMENT_TRANSFER_METHOD, mTransferMethod); super.onSaveInstanceState(outState); @@ -298,26 +296,37 @@ public void notifyTransferMethodAdded(@NonNull final HyperwalletTransferMethod t } @Override - public void showTransferMethodFields(@NonNull final List fields) { + public void showTransferMethodFields(@NonNull final List fields) { mDynamicContainer.removeAllViews(); - int previousView = 0; + try { - for (final HyperwalletField field : fields) { - AbstractWidget widget = WidgetFactory - .newWidget(field, this, getContext(), - mWidgetInputStateHashMap.containsKey(field.getName()) ? - mWidgetInputStateHashMap.get(field.getName()).getValue() : "", - mCreateTransferMethodButton); - if (mWidgetInputStateHashMap.isEmpty() || !mWidgetInputStateHashMap.containsKey(widget.getName())) { - mWidgetInputStateHashMap.put(widget.getName(), widget.getWidgetInputState()); - } + Locale locale = new Locale.Builder().setRegion(mCountry).build(); + // group + for (HyperwalletFieldGroup group : fields) { + View sectionHeader = LayoutInflater.from(mDynamicContainer.getContext()) + .inflate(R.layout.item_widget_section_header, mDynamicContainer, false); + TextView sectionTitle = sectionHeader.findViewById(R.id.section_header_title); + sectionTitle.setText(getSectionHeaderText(group, locale)); + sectionHeader.setId(View.generateViewId()); + mDynamicContainer.addView(sectionHeader); + + // group fields + for (final HyperwalletField field : group.getFields()) { + AbstractWidget widget = WidgetFactory + .newWidget(field, this, mWidgetInputStateHashMap.containsKey(field.getName()) ? + mWidgetInputStateHashMap.get(field.getName()).getValue() : "", + mCreateTransferMethodButton); + if (mWidgetInputStateHashMap.isEmpty() || !mWidgetInputStateHashMap.containsKey(widget.getName())) { + mWidgetInputStateHashMap.put(widget.getName(), widget.getWidgetInputState()); + } - View widgetView = widget.getView(); - widgetView.setTag(widget); - previousView = placeBelow(widgetView, previousView, true); - final String error = mWidgetInputStateHashMap.get(widget.getName()).getErrorMessage(); - widget.showValidationError(error); - mDynamicContainer.addView(widgetView); + View widgetView = widget.getView(mDynamicContainer); + widgetView.setTag(widget); + widgetView.setId(View.generateViewId()); + final String error = mWidgetInputStateHashMap.get(widget.getName()).getErrorMessage(); + widget.showValidationError(error); + mDynamicContainer.addView(widgetView); + } } if (mShowCreateProgressBar) { @@ -328,8 +337,20 @@ public void showTransferMethodFields(@NonNull final List field } } + private String getSectionHeaderText(@NonNull final HyperwalletFieldGroup group, @NonNull final Locale locale) { + if (group.getGroupName().equals(HyperwalletFieldGroup.GroupTypes.ACCOUNT_INFORMATION)) { + return requireContext().getResources() + .getString(R.string.account_information_section_header, locale.getDisplayName(), mCurrency); + } + + return requireContext().getString(requireContext().getResources() + .getIdentifier(group.getGroupName().toLowerCase(Locale.ROOT), "string", + requireContext().getPackageName())); + } + @Override - public void showTransactionInformation(@NonNull final List fees, @Nullable final String processingTime) { + public void showTransactionInformation(@NonNull final List fees, + @Nullable final String processingTime) { View header = getView().findViewById(R.id.add_transfer_method_static_container_header); View container = getView().findViewById(R.id.add_transfer_method_static_container); View feeLabel = getView().findViewById(R.id.add_transfer_method_fee_label); @@ -420,7 +441,7 @@ public void showInputErrors(List errors) { AbstractWidget widget = (AbstractWidget) view.getTag(); if (widget.getName().equals(error.getFieldName())) { if (!focusSet) { - widget.getView().requestFocus(); + widget.getView(mDynamicContainer).requestFocus(); focusSet = true; } widget.showValidationError(error.getMessage()); @@ -497,6 +518,8 @@ private void triggerSubmit() { mTransferMethod.setField(widget.getName(), widget.getValue()); } } + + mTransferMethod.setField(PROFILE_TYPE, mTransferMethodProfileType); mPresenter.createTransferMethod(mTransferMethod); } } @@ -524,25 +547,6 @@ private void setVisibleAndDisableFields() { mCreateTransferMethodButton.setBackgroundColor(getResources().getColor(R.color.colorSecondaryDark)); } - private int placeBelow(View v, int previousId, boolean matchParentWidth) { - RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams( - matchParentWidth ? ViewGroup.LayoutParams.MATCH_PARENT : ViewGroup.LayoutParams.WRAP_CONTENT, - ViewGroup.LayoutParams.WRAP_CONTENT); - - if (previousId != 0) { - params.addRule(RelativeLayout.BELOW, previousId); - } - - int margin = (int) (getContext().getResources().getDimension(R.dimen.default_margin) - / getContext().getResources().getDisplayMetrics().density); - - params.setMargins(margin, margin, margin, margin); - v.setId(View.generateViewId()); - v.setLayoutParams(params); - - return v.getId(); - } - private boolean performValidation(boolean bypassFocusCheck) { boolean valid = true; // this is added since some phones triggers the create button but the widgets are not yet initialized @@ -569,16 +573,7 @@ private boolean performValidation(boolean bypassFocusCheck) { } } } - return valid && hasWidget && haveAllWidgetsReceivedFocus(); - } - - private boolean haveAllWidgetsReceivedFocus() { - for (String key : mWidgetInputStateHashMap.keySet()) { - if (!mWidgetInputStateHashMap.get(key).hasFocused()) { - return false; - } - } - return true; + return valid && hasWidget; } @Override diff --git a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodPresenter.java b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodPresenter.java index 73b10717d..8373668bd 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodPresenter.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodPresenter.java @@ -17,16 +17,14 @@ package com.hyperwallet.android.ui.transfermethod; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import com.hyperwallet.android.model.HyperwalletErrors; import com.hyperwallet.android.model.HyperwalletTransferMethod; -import com.hyperwallet.android.model.meta.Fee; -import com.hyperwallet.android.model.meta.HyperwalletTransferMethodConfigurationFieldResult; +import com.hyperwallet.android.model.meta.HyperwalletTransferMethodConfigurationField; import com.hyperwallet.android.ui.repository.TransferMethodConfigurationRepository; import com.hyperwallet.android.ui.repository.TransferMethodRepository; -import java.util.List; - public class AddTransferMethodPresenter implements AddTransferMethodContract.Presenter { private static final String TAG = AddTransferMethodContract.class.getName(); @@ -87,21 +85,16 @@ public void loadTransferMethodConfigurationFields(final boolean forceUpdate, @No country, currency, transferMethodType, transferMethodProfileType, new TransferMethodConfigurationRepository.LoadFieldsCallback() { @Override - public void onFieldsLoaded( - HyperwalletTransferMethodConfigurationFieldResult transferMethodConfigurationFieldResult) { + public void onFieldsLoaded(HyperwalletTransferMethodConfigurationField field, + @Nullable final String processingTime) { if (!mView.isActive()) { return; } mView.hideProgressBar(); - mView.showTransferMethodFields(transferMethodConfigurationFieldResult.getFields()); + mView.showTransferMethodFields(field.getFields().getFieldGroups()); // there can be multiple fees when we have flat fee + percentage fees - List fees = transferMethodConfigurationFieldResult - .getFees(country, currency, transferMethodType, transferMethodProfileType); - mView.showTransactionInformation(fees, - transferMethodConfigurationFieldResult - .getProcessingTime(country, currency, transferMethodType, - transferMethodProfileType)); + mView.showTransactionInformation(field.getFees(), processingTime); } @Override diff --git a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/FeeFormatter.java b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/FeeFormatter.java index 95cf1cf22..095c218c7 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/FeeFormatter.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/FeeFormatter.java @@ -23,13 +23,13 @@ import androidx.annotation.NonNull; import com.hyperwallet.android.hyperwallet_ui.R; -import com.hyperwallet.android.model.meta.Fee; +import com.hyperwallet.android.model.meta.HyperwalletFee; import java.util.List; public class FeeFormatter { - public static String getFormattedFee(@NonNull final Context context, @NonNull final List fees) { + public static String getFormattedFee(@NonNull final Context context, @NonNull final List fees) { String formattedString = context.getResources().getString(R.string.unknown); if (fees.size() == 1) { formattedString = getSingleFormattedFee(context, fees, formattedString); @@ -39,13 +39,13 @@ public static String getFormattedFee(@NonNull final Context context, @NonNull fi return formattedString; } - private static String getSingleFormattedFee(@NonNull Context context, @NonNull List fees, + private static String getSingleFormattedFee(@NonNull Context context, @NonNull List fees, String formattedString) { - Fee fee = fees.get(0); - if (Fee.FeeRate.FLAT.equals(fee.getFeeRateType())) { + HyperwalletFee fee = fees.get(0); + if (HyperwalletFee.FeeRate.FLAT.equals(fee.getFeeRateType())) { formattedString = context.getResources().getString(R.string.fee_flat_formatter, fee.getCurrency(), fee.getValue()); - } else if (Fee.FeeRate.PERCENT.equals(fee.getFeeRateType())) { + } else if (HyperwalletFee.FeeRate.PERCENT.equals(fee.getFeeRateType())) { formattedString = getPercentFormattedFee(context, fee); } return formattedString; @@ -53,20 +53,20 @@ private static String getSingleFormattedFee(@NonNull Context context, @NonNull L // we expect at the most 2 fees and in that case one should be flat and other percent // which will be formatted to USD 3.00 + 3% (Min: USD 1.00, Max: USD 15.00) - private static String getMixFormattedFee(@NonNull Context context, @NonNull List fees, + private static String getMixFormattedFee(@NonNull Context context, @NonNull List fees, String formattedString) { - Fee flatFee = null; - Fee percentFee = null; - for (Fee fee : fees) { - if (Fee.FeeRate.FLAT.equals(fee.getFeeRateType())) { + HyperwalletFee flatFee = null; + HyperwalletFee percentFee = null; + for (HyperwalletFee fee : fees) { + if (HyperwalletFee.FeeRate.FLAT.equals(fee.getFeeRateType())) { flatFee = fee; - } else if (Fee.FeeRate.PERCENT.equals(fee.getFeeRateType())) { + } else if (HyperwalletFee.FeeRate.PERCENT.equals(fee.getFeeRateType())) { percentFee = fee; } } if (flatFee != null && percentFee != null) { - String minimumAmount = percentFee.getMinimum(); - String maximumAmount = percentFee.getMaximum(); + String minimumAmount = percentFee.getMin(); + String maximumAmount = percentFee.getMax(); if (maximumAmount.isEmpty() && minimumAmount.isEmpty()) { formattedString = context.getResources().getString(R.string.fee_mix_no_min_and_max_formatter, flatFee.getCurrency(), flatFee.getValue(), percentFee.getValue()); @@ -85,10 +85,10 @@ private static String getMixFormattedFee(@NonNull Context context, @NonNull List } - private static String getPercentFormattedFee(@NonNull final Context context, @NonNull final Fee fee) { + private static String getPercentFormattedFee(@NonNull final Context context, @NonNull final HyperwalletFee fee) { String formattedFee; - String minimumAmount = fee.getMinimum(); - String maximumAmount = fee.getMaximum(); + String minimumAmount = fee.getMin(); + String maximumAmount = fee.getMax(); if (maximumAmount.isEmpty() && minimumAmount.isEmpty()) { formattedFee = context.getResources().getString(R.string.fee_percent_no_min_and_max_formatter, fee.getValue()); diff --git a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/ListTransferMethodPresenter.java b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/ListTransferMethodPresenter.java index ece9b89d9..5480e0a2e 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/ListTransferMethodPresenter.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/ListTransferMethodPresenter.java @@ -38,7 +38,7 @@ public ListTransferMethodPresenter(TransferMethodRepository repository, ListTran @Override public void loadTransferMethods() { mView.showProgressBar(); - mTransferMethodRepository.loadTransferMethod(new TransferMethodRepository.LoadTransferMethodListCallback() { + mTransferMethodRepository.loadTransferMethods(new TransferMethodRepository.LoadTransferMethodListCallback() { @Override public void onTransferMethodListLoaded(List transferMethods) { if (!mView.isActive()) { diff --git a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/SelectTransferMethodFragment.java b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/SelectTransferMethodFragment.java index db873d8f7..193aefd14 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/SelectTransferMethodFragment.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/SelectTransferMethodFragment.java @@ -19,7 +19,6 @@ package com.hyperwallet.android.ui.transfermethod; import static com.hyperwallet.android.ui.transfermethod.TransferMethodUtils.getStringFontIcon; -import static com.hyperwallet.android.ui.transfermethod.TransferMethodUtils.getStringResourceByName; import android.annotation.SuppressLint; import android.content.Context; @@ -457,8 +456,7 @@ class ViewHolder extends RecyclerView.ViewHolder { @SuppressLint("StringFormatInvalid") void bind(TransferMethodSelectionItem selectionItem) { - mTitle.setText( - getStringResourceByName(mTitle.getContext(), selectionItem.getTransferMethodType())); + mTitle.setText(selectionItem.getTransferMethodName()); mIcon.setText( getStringFontIcon(mIcon.getContext(), selectionItem.getTransferMethodType())); @@ -466,6 +464,7 @@ void bind(TransferMethodSelectionItem selectionItem) { String formattedFee = FeeFormatter.getFormattedFee(mTitle.getContext(), selectionItem.getFees()); mDescriptionFees.setText(mDescriptionFees.getContext() .getString(R.string.select_transfer_method_item_fee_information, formattedFee)); + mDescriptionFees.setVisibility(View.VISIBLE); } else { mDescriptionFees.setVisibility(View.GONE); } @@ -474,6 +473,7 @@ void bind(TransferMethodSelectionItem selectionItem) { mDescriptionProcessingTime.setText(mDescriptionProcessingTime.getContext() .getString(R.string.select_transfer_method_item_processing_time_information, selectionItem.getProcessingTime())); + mDescriptionProcessingTime.setVisibility(View.VISIBLE); } else { mDescriptionProcessingTime.setVisibility(View.INVISIBLE); } diff --git a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/SelectTransferMethodPresenter.java b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/SelectTransferMethodPresenter.java index 4524e8ff0..e5e49cb59 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/SelectTransferMethodPresenter.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/SelectTransferMethodPresenter.java @@ -15,7 +15,6 @@ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ - package com.hyperwallet.android.ui.transfermethod; import androidx.annotation.NonNull; @@ -23,15 +22,17 @@ import com.hyperwallet.android.model.HyperwalletErrors; import com.hyperwallet.android.model.HyperwalletUser; -import com.hyperwallet.android.model.meta.Fee; -import com.hyperwallet.android.model.meta.HyperwalletTransferMethodConfigurationKeyResult; +import com.hyperwallet.android.model.meta.HyperwalletTransferMethodConfigurationKey; +import com.hyperwallet.android.model.meta.keyed.Country; +import com.hyperwallet.android.model.meta.keyed.Currency; +import com.hyperwallet.android.model.meta.keyed.HyperwalletTransferMethodType; import com.hyperwallet.android.ui.repository.TransferMethodConfigurationRepository; import com.hyperwallet.android.ui.repository.UserRepository; import java.util.ArrayList; -import java.util.Currency; +import java.util.HashSet; import java.util.List; -import java.util.Locale; +import java.util.Set; import java.util.TreeMap; public class SelectTransferMethodPresenter implements SelectTransferMethodContract.Presenter { @@ -64,20 +65,21 @@ public void onUserLoaded(@NonNull final HyperwalletUser user) { mTransferMethodConfigurationRepository.getKeys( new TransferMethodConfigurationRepository.LoadKeysCallback() { @Override - public void onKeysLoaded( - @Nullable final HyperwalletTransferMethodConfigurationKeyResult transferMethodConfigurationKeyResult) { + public void onKeysLoaded(@Nullable final HyperwalletTransferMethodConfigurationKey key) { if (!mView.isActive()) { return; } mView.hideProgressBar(); - List transferMethodTypes = - transferMethodConfigurationKeyResult.getTransferMethods(countryCode, - currencyCode, user.getProfileType()); + Set transferMethodTypes = + key.getTransferMethodType(countryCode, currencyCode) != null + ? key.getTransferMethodType(countryCode, currencyCode) : + new HashSet(); mView.showTransferMethodCountry(countryCode); mView.showTransferMethodCurrency(currencyCode); - mView.showTransferMethodTypes(getTransferMethodSelectionItems(countryCode, currencyCode, - user.getProfileType(), transferMethodTypes, transferMethodConfigurationKeyResult)); + mView.showTransferMethodTypes( + getTransferMethodSelectionItems(countryCode, currencyCode, + user.getProfileType(), transferMethodTypes)); } @Override @@ -110,24 +112,28 @@ public void loadCurrency(final boolean forceUpdate, @NonNull final String countr } mUserRepository.loadUser(new UserRepository.LoadUserCallback() { - @Override public void onUserLoaded(@NonNull final HyperwalletUser user) { mTransferMethodConfigurationRepository.getKeys( new TransferMethodConfigurationRepository.LoadKeysCallback() { @Override - public void onKeysLoaded( - @Nullable final HyperwalletTransferMethodConfigurationKeyResult result) { + public void onKeysLoaded(@Nullable final HyperwalletTransferMethodConfigurationKey key) { if (!mView.isActive()) { return; } - List transferMethodCurrencies = result.getCurrencies(countryCode); - List transferMethodTypes = result.getTransferMethods( - countryCode, transferMethodCurrencies.get(0), user.getProfileType()); + List currencies = key.getCurrencies(countryCode) != null ? + new ArrayList<>(key.getCurrencies(countryCode)) : + new ArrayList(); + String currencyCode = currencies.get(0).getCode(); + Set transferMethodTypes = + key.getTransferMethodType(countryCode, currencyCode) != null ? + key.getTransferMethodType(countryCode, currencyCode) : + new HashSet(); mView.showTransferMethodCountry(countryCode); - mView.showTransferMethodCurrency(transferMethodCurrencies.get(0)); + mView.showTransferMethodCurrency(currencies.get(0).getCode()); mView.showTransferMethodTypes(getTransferMethodSelectionItems(countryCode, - transferMethodCurrencies.get(0), user.getProfileType(), transferMethodTypes, result)); + currencies.get(0).getCode(), + user.getProfileType(), transferMethodTypes)); } @Override @@ -142,7 +148,6 @@ public void onError(@NonNull HyperwalletErrors errors) { showErrorLoadCurrency(errors); } }); - } private void showErrorLoadCurrency(@NonNull HyperwalletErrors errors) { @@ -165,20 +170,20 @@ public void onUserLoaded(@NonNull final HyperwalletUser user) { mTransferMethodConfigurationRepository.getKeys( new TransferMethodConfigurationRepository.LoadKeysCallback() { @Override - public void onKeysLoaded(@Nullable final HyperwalletTransferMethodConfigurationKeyResult - transferMethodConfigurationKeyResult) { + public void onKeysLoaded(@Nullable final HyperwalletTransferMethodConfigurationKey key) { if (!mView.isActive()) { return; } - List transferMethodTypes = - transferMethodConfigurationKeyResult.getTransferMethods( - countryCode, currencyCode, user.getProfileType()); - + Set transferMethodTypes = + key.getTransferMethodType(countryCode, currencyCode) != null ? + key.getTransferMethodType(countryCode, currencyCode) : + new HashSet(); mView.showTransferMethodCountry(countryCode); mView.showTransferMethodCurrency(currencyCode); - mView.showTransferMethodTypes(getTransferMethodSelectionItems(countryCode, currencyCode, - user.getProfileType(), transferMethodTypes, transferMethodConfigurationKeyResult)); + mView.showTransferMethodTypes( + getTransferMethodSelectionItems(countryCode, currencyCode, + user.getProfileType(), transferMethodTypes)); } @Override @@ -199,7 +204,6 @@ public void onError(@NonNull HyperwalletErrors errors) { mView.showErrorLoadTransferMethodTypes(errors.getErrors()); } }); - } @Override @@ -212,21 +216,21 @@ public void openAddTransferMethod(@NonNull final String country, @NonNull final public void loadCountrySelection(@NonNull final String countryCode) { mTransferMethodConfigurationRepository.getKeys(new TransferMethodConfigurationRepository.LoadKeysCallback() { @Override - public void onKeysLoaded( - @Nullable final HyperwalletTransferMethodConfigurationKeyResult transferMethodConfigurationKeyResult) { + public void onKeysLoaded(@Nullable final HyperwalletTransferMethodConfigurationKey key) { if (!mView.isActive()) { return; } - List countryCodes = transferMethodConfigurationKeyResult.getCountries(); + Set countries = key.getCountries(); TreeMap countryNameCodeMap = new TreeMap<>(); - Locale.Builder builder = new Locale.Builder(); - for (String countryCode : countryCodes) { - Locale locale = builder.setRegion(countryCode).build(); - countryNameCodeMap.put(locale.getDisplayName(), countryCode); + String selectedCountryName = ""; + for (Country country : countries) { + if (country.getCode().equals(countryCode)) { + selectedCountryName = country.getName(); + } + countryNameCodeMap.put(country.getName(), country.getCode()); } - Locale locale = new Locale.Builder().setRegion(countryCode).build(); - mView.showCountrySelectionDialog(countryNameCodeMap, locale.getDisplayName()); + mView.showCountrySelectionDialog(countryNameCodeMap, selectedCountryName); } @Override @@ -242,20 +246,23 @@ public void onError(@NonNull final HyperwalletErrors errors) { public void loadCurrencySelection(@NonNull final String countryCode, @NonNull final String currencyCode) { mTransferMethodConfigurationRepository.getKeys(new TransferMethodConfigurationRepository.LoadKeysCallback() { @Override - public void onKeysLoaded( - @Nullable HyperwalletTransferMethodConfigurationKeyResult transferMethodConfigurationKeyResult) { + public void onKeysLoaded(@Nullable HyperwalletTransferMethodConfigurationKey key) { if (!mView.isActive()) { return; } - List currencyCodes = transferMethodConfigurationKeyResult.getCurrencies(countryCode); + Set currencyCodes = key.getCurrencies(countryCode) != null ? + key.getCurrencies(countryCode) : new HashSet(); + TreeMap currencyNameCodeMap = new TreeMap<>(); - for (String currencyCode : currencyCodes) { - Currency currency = Currency.getInstance(currencyCode); - currencyNameCodeMap.put(currency.getDisplayName(), currencyCode); + String selectedCurrencyName = ""; + for (Currency currency : currencyCodes) { + if (currency.getCode().equals(currencyCode)) { + selectedCurrencyName = currency.getName(); + } + currencyNameCodeMap.put(currency.getName(), currency.getCode()); } - mView.showCurrencySelectionDialog(currencyNameCodeMap, - Currency.getInstance(currencyCode).getDisplayName()); + mView.showCurrencySelectionDialog(currencyNameCodeMap, selectedCurrencyName); } @Override @@ -269,20 +276,17 @@ public void onError(@NonNull final HyperwalletErrors errors) { } private List getTransferMethodSelectionItems( - @NonNull final String country, @NonNull final String currency, + @NonNull final String countryCode, @NonNull final String currencyCode, @NonNull final String userProfileType, - @NonNull final List transferMethodTypes, - @NonNull final HyperwalletTransferMethodConfigurationKeyResult result) { + @NonNull final Set transferMethodTypes) { List selectionItems = new ArrayList<>(); - for (String transferMethodType : transferMethodTypes) { - List fees = result.getFees(country, currency, transferMethodType, userProfileType); - String processingTime = result.getProcessingTime(country, currency, transferMethodType, userProfileType); - TransferMethodSelectionItem data = new TransferMethodSelectionItem(country, currency, userProfileType, - transferMethodType, processingTime, fees); + for (HyperwalletTransferMethodType transferMethodType : transferMethodTypes) { + TransferMethodSelectionItem data = new TransferMethodSelectionItem(countryCode, currencyCode, + userProfileType, transferMethodType.getCode(), transferMethodType.getName(), + transferMethodType.getProcessingTime(), transferMethodType.getFees()); selectionItems.add(data); } return selectionItems; } - } diff --git a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/TransferMethodSelectionItem.java b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/TransferMethodSelectionItem.java index d065d7ac1..c3c7af373 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/TransferMethodSelectionItem.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/TransferMethodSelectionItem.java @@ -18,29 +18,34 @@ import androidx.annotation.NonNull; -import com.hyperwallet.android.model.meta.Fee; +import com.hyperwallet.android.model.meta.HyperwalletFee; +import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.Set; public class TransferMethodSelectionItem { private final String mCountry; private final String mCurrency; - private final List mFees; + private final List mFees; private final String mProcessingTime; private final String mProfileType; private final String mTransferMethodType; + private final String mTransferMethodName; public TransferMethodSelectionItem(@NonNull final String country, @NonNull final String currency, @NonNull final String profileType, @NonNull final String transferMethodType, - @NonNull final String processingTime, @NonNull final List fees) { + @NonNull final String transferMethodName, @NonNull final String processingTime, + @NonNull final Set fees) { mCountry = country; mCurrency = currency; mProfileType = profileType; mTransferMethodType = transferMethodType; + mTransferMethodName = transferMethodName; mProcessingTime = processingTime; - mFees = fees; + mFees = new ArrayList<>(fees); } public String getCountry() { @@ -55,6 +60,10 @@ public String getProfileType() { return mProfileType; } + public String getTransferMethodName() { + return mTransferMethodName; + } + public String getTransferMethodType() { return mTransferMethodType; } @@ -63,7 +72,7 @@ public String getProcessingTime() { return mProcessingTime; } - public List getFees() { + public List getFees() { return mFees; } diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/WidgetSelectionDialogFragment.java b/ui/src/main/java/com/hyperwallet/android/ui/view/WidgetSelectionDialogFragment.java index 7bed35b21..5dab1341b 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/view/WidgetSelectionDialogFragment.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/view/WidgetSelectionDialogFragment.java @@ -16,19 +16,27 @@ */ package com.hyperwallet.android.ui.view; +import android.app.SearchManager; import android.content.Context; import android.os.Build; import android.os.Bundle; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; +import android.view.inputmethod.EditorInfo; +import android.widget.Filter; +import android.widget.Filterable; import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.SearchView; import androidx.appcompat.widget.Toolbar; import androidx.core.content.ContextCompat; import androidx.fragment.app.DialogFragment; @@ -41,19 +49,23 @@ import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.TreeMap; public class WidgetSelectionDialogFragment extends DialogFragment implements ToolbarEventListener { public static final String TAG = WidgetSelectionDialogFragment.class.getName(); private static final String ARGUMENT_NAME_VALUE_MAP = "ARGUMENT_NAME_VALUE_MAP"; + private static final String ARGUMENT_SEARCH_SELECTED_NAME_QUERY = "ARGUMENT_SEARCH_SELECTED_NAME_QUERY"; private static final String ARGUMENT_SELECTED_NAME = "ARGUMENT_SELECTED_NAME"; private static final String ARGUMENT_SELECTION_LABEL = "ARGUMENT_SELECTION_LABEL"; private static final String ARGUMENT_SELECTION_FIELD_NAME = "ARGUMENT_SELECTION_FIELD_NAME"; + private static final int MAX_NO_SEARCH_COUNT = 20; private Adapter mAdapter; private String mFieldName; private TreeMap mNameValueMap; + private String mSearchNameQuery; private String mSelectedName; private String mSelectionLabel; private WidgetSelectionItemListener mWidgetSelectionItemListener; @@ -66,12 +78,14 @@ public static WidgetSelectionDialogFragment newInstance(@NonNull final TreeMap MAX_NO_SEARCH_COUNT); + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + menu.clear(); + inflater.inflate(R.menu.menu_widget_selection, menu); + + SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE); + MenuItem searchItem = menu.findItem(R.id.widget_selection_search_item); + SearchView searchView = (SearchView) searchItem.getActionView(); + searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName())); + searchView.setMaxWidth(Integer.MAX_VALUE); + searchView.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI); + searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { + @Override + public boolean onQueryTextSubmit(String query) { + mSearchNameQuery = query; + mAdapter.getFilter().filter(query); + return false; + } + + @Override + public boolean onQueryTextChange(String newText) { + mSearchNameQuery = newText; + mAdapter.getFilter().filter(newText); + return false; + } + }); + + if (!mSearchNameQuery.isEmpty()) { + searchView.clearFocus(); + searchItem.expandActionView(); + searchView.setQuery(mSearchNameQuery, true); } } @@ -181,15 +232,16 @@ public interface WidgetSelectionItemListener { void onWidgetSelectionItemClicked(@NonNull final String selectedValue, @NonNull final String fieldName); } - private static class Adapter extends RecyclerView.Adapter { + private static class Adapter extends RecyclerView.Adapter implements Filterable { + private final Fragment mFragment; + private final String mFieldName; private final TreeMap mNameValueMap; private final String mSelectedName; - private final List mSelectionList; private final ToolbarEventListener mToolbarEventListener; - private final Fragment mFragment; - private final String mFieldName; private final WidgetSelectionItemListener mWidgetSelectionItemListener; + private TreeMap mNameValueFilteredMap; + private List mSelectionList; Adapter(@NonNull final TreeMap nameValueMap, @NonNull final String selectedName, @NonNull final Fragment fragment, @NonNull final ToolbarEventListener toolbarEventListener, @@ -198,6 +250,7 @@ private static class Adapter extends RecyclerView.Adapter { mSelectionList = new ArrayList<>(nameValueMap.keySet()); mSelectedName = selectedName; mNameValueMap = nameValueMap; + mNameValueFilteredMap = nameValueMap; mToolbarEventListener = toolbarEventListener; mFragment = fragment; mFieldName = fieldName; @@ -243,6 +296,37 @@ String getItemValue(int position) { return mNameValueMap.get(mSelectionList.get(position)); } + @Override + public Filter getFilter() { + return new Filter() { + @Override + protected FilterResults performFiltering(CharSequence constraint) { + if (constraint.length() == 0) { + mSelectionList = new ArrayList<>(mNameValueMap.keySet()); + mNameValueFilteredMap = mNameValueMap; + } else { + mNameValueFilteredMap = new TreeMap<>(); + for (String selection : mNameValueMap.keySet()) { + if (selection.toLowerCase(Locale.ROOT) + .contains(constraint.toString().toLowerCase(Locale.ROOT))) { + mNameValueFilteredMap.put(selection, mNameValueMap.get(selection)); + } + } + mSelectionList = new ArrayList<>(mNameValueFilteredMap.keySet()); + } + FilterResults filterResults = new FilterResults(); + filterResults.values = mNameValueFilteredMap; + return filterResults; + } + + @Override + protected void publishResults(CharSequence constraint, FilterResults results) { + mNameValueFilteredMap = (TreeMap) results.values; + notifyDataSetChanged(); + } + }; + } + class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { final TextView mSelectName; final ImageView mSelectItemImage; diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/AbstractWidget.java b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/AbstractWidget.java index 9ec0cec5d..211e120c6 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/AbstractWidget.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/AbstractWidget.java @@ -16,8 +16,6 @@ */ package com.hyperwallet.android.ui.view.widget; -import android.content.Context; -import android.os.Build; import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup; @@ -26,14 +24,12 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.hyperwallet.android.hyperwallet_ui.R; -import com.hyperwallet.android.model.meta.HyperwalletField; +import com.hyperwallet.android.model.meta.field.HyperwalletField; public abstract class AbstractWidget { private static final String LABEL_SUFFIX = "Label"; - protected final Context mContext; protected final View mDefaultFocusView; protected final String mDefaultValue; protected final HyperwalletField mField; @@ -42,16 +38,15 @@ public abstract class AbstractWidget { protected WidgetInputState mWidgetInputState; public AbstractWidget(@Nullable HyperwalletField field, @NonNull WidgetEventListener listener, - @NonNull Context context, @Nullable String defaultValue, @NonNull View defaultFocusView) { + @Nullable String defaultValue, @NonNull View defaultFocusView) { mField = field; mListener = listener; - mContext = context; mDefaultValue = defaultValue; mDefaultFocusView = defaultFocusView; mWidgetInputState = new WidgetInputState(getName()); } - public abstract View getView(); + public abstract View getView(@NonNull final ViewGroup viewGroup); public String getName() { return mField == null ? "" : mField.getName(); @@ -128,17 +123,6 @@ protected void appendLayout(View v, boolean matchParentWidth) { params.addRule(RelativeLayout.BELOW, mBottomViewId); } - int default_margin = (int) (mContext.getResources().getDimension(R.dimen.default_margin) - / mContext.getResources().getDisplayMetrics().density); - int widget_margin_offset = (int) (mContext.getResources().getDimension(R.dimen.widget_left_margin_offset) - / mContext.getResources().getDisplayMetrics().density); - - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) { - params.setMargins(default_margin, default_margin, default_margin, default_margin); - } else { - params.setMargins(widget_margin_offset, default_margin, default_margin, default_margin); - } - v.setLayoutParams(params); mBottomViewId = v.getId(); } @@ -148,7 +132,7 @@ protected void setIdFromFieldName(View view) { if (fieldName.isEmpty()) { view.setId(View.generateViewId()); } else { - view.setId(getIdByResourceName(fieldName)); + view.setId(getIdByResourceName(fieldName, view)); } } @@ -157,17 +141,15 @@ protected void setIdFromFieldLabel(View view) { if (fieldName.isEmpty()) { view.setId(View.generateViewId()); } else { - view.setId(getIdByResourceName(fieldName + LABEL_SUFFIX)); + view.setId(getIdByResourceName(fieldName + LABEL_SUFFIX, view)); } } - private int getIdByResourceName(@NonNull final String fieldName) { - int id; - final int idFromResource = mContext.getResources().getIdentifier(fieldName, "id", - mContext.getPackageName()); - // Returns 0 if no such resource was found. - id = idFromResource == 0 ? View.generateViewId() : idFromResource; - return id; + private int getIdByResourceName(@NonNull final String fieldName, @NonNull final View view) { + final int idFromResource = view.getContext().getResources().getIdentifier(fieldName, "id", + view.getContext().getPackageName()); + + return idFromResource == 0 ? View.generateViewId() : idFromResource; } protected class DefaultKeyListener implements View.OnKeyListener { diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateWidget.java b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateWidget.java index a3ba9d932..e4f4edc44 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateWidget.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateWidget.java @@ -16,45 +16,50 @@ */ package com.hyperwallet.android.ui.view.widget; -import android.content.Context; import android.text.Editable; import android.text.InputType; +import android.text.TextUtils; import android.text.TextWatcher; import android.view.ContextThemeWrapper; +import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import android.widget.EditText; -import android.widget.RelativeLayout; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.google.android.material.textfield.TextInputLayout; import com.hyperwallet.android.hyperwallet_ui.R; -import com.hyperwallet.android.model.meta.HyperwalletField; +import com.hyperwallet.android.model.meta.field.HyperwalletField; public class DateWidget extends AbstractWidget { private ViewGroup mContainer; - private String mValue = ""; + private String mValue; private TextInputLayout mTextInputLayout; - public DateWidget(@NonNull HyperwalletField field, @NonNull WidgetEventListener listener, @NonNull Context context, + public DateWidget(@NonNull HyperwalletField field, @NonNull WidgetEventListener listener, @Nullable String defaultValue, @NonNull View defaultFocusView) { - super(field, listener, context, defaultValue, defaultFocusView); + super(field, listener, defaultValue, defaultFocusView); mValue = defaultValue; } @Override - public View getView() { + public View getView(@NonNull final ViewGroup viewGroup) { if (mContainer == null) { - mContainer = new RelativeLayout(mContext); - mTextInputLayout = new TextInputLayout( - new ContextThemeWrapper(mContext, R.style.Widget_Hyperwallet_TextInputLayout)); + mContainer = (ViewGroup) LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.item_widget_layout, viewGroup, false); + // input control + mTextInputLayout = new TextInputLayout(new ContextThemeWrapper(viewGroup.getContext(), + mField.isEditable() ? R.style.Widget_Hyperwallet_TextInputLayout + : R.style.Widget_Hyperwallet_TextInputLayout_Disabled)); final EditText editText = new EditText( - new ContextThemeWrapper(mContext, R.style.Widget_Hyperwallet_TextInputEditText)); + new ContextThemeWrapper(viewGroup.getContext(), R.style.Widget_Hyperwallet_TextInputEditText)); + + editText.setEnabled(mField.isEditable()); setIdFromFieldName(editText); mTextInputLayout.setHint(mField.getLabel()); mTextInputLayout.addView(editText); @@ -88,10 +93,10 @@ public void afterTextChanged(Editable s) { } }); + editText.setText(TextUtils.isEmpty(mDefaultValue) ? mField.getValue() : mDefaultValue); editText.setInputType(InputType.TYPE_CLASS_DATETIME); editText.setOnKeyListener(new DefaultKeyListener(mDefaultFocusView, editText)); editText.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI | EditorInfo.IME_ACTION_NEXT); - editText.setText(mDefaultValue); appendLayout(mTextInputLayout, true); mContainer.addView(mTextInputLayout); } diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DefaultAccountWidget.java b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DefaultAccountWidget.java index fc1e66687..9463f308f 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DefaultAccountWidget.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DefaultAccountWidget.java @@ -2,7 +2,6 @@ import static com.hyperwallet.android.model.HyperwalletTransferMethod.TransferMethodFields.IS_DEFAULT_TRANSFER_METHOD; -import android.content.Context; import android.graphics.Typeface; import android.view.View; import android.view.ViewGroup; @@ -21,9 +20,9 @@ public class DefaultAccountWidget extends AbstractWidget { private ViewGroup mContainer; private String mValue; - public DefaultAccountWidget(@NonNull WidgetEventListener listener, @NonNull Context context, + public DefaultAccountWidget(@NonNull WidgetEventListener listener, @Nullable String defaultValue, @NonNull View defaultFocusView) { - super(null, listener, context, defaultValue, defaultFocusView); + super(null, listener, defaultValue, defaultFocusView); } @Override @@ -32,26 +31,26 @@ public String getName() { } @Override - public View getView() { + public View getView(@NonNull final ViewGroup viewGroup) { if (mContainer == null) { - mContainer = new RelativeLayout(mContext); + mContainer = new RelativeLayout(viewGroup.getContext()); // label - TextView label = new TextView(mContext); - label.setText(mContext.getResources().getText(R.string.default_account_label)); + TextView label = new TextView(viewGroup.getContext()); + label.setText(viewGroup.getContext().getResources().getText(R.string.default_account_label)); - label.setTextSize(mContext.getResources().getDimension(R.dimen.font_subtitle2)); + label.setTextSize(viewGroup.getContext().getResources().getDimension(R.dimen.font_subtitle2)); setIdFromFieldLabel(label); label.setTypeface(null, Typeface.BOLD); - label.setTextColor(mContext.getResources().getColor(R.color.colorPrimary)); + label.setTextColor(viewGroup.getContext().getResources().getColor(R.color.colorPrimary)); appendLayout(label, true); mContainer.addView(label); // switch control - Switch toggle = new Switch(mContext); + Switch toggle = new Switch(viewGroup.getContext()); setIdFromFieldName(toggle); - toggle.setText(mContext.getResources().getText(R.string.default_account_sub_label)); - toggle.setTextSize(mContext.getResources().getDimension(R.dimen.font_subtitle2)); + toggle.setText(viewGroup.getContext().getResources().getText(R.string.default_account_sub_label)); + toggle.setTextSize(viewGroup.getContext().getResources().getDimension(R.dimen.font_subtitle2)); if (mDefaultValue == null) { toggle.setChecked(true); // initial state mValue = Boolean.TRUE.toString(); diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/ExpiryDateWidget.java b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/ExpiryDateWidget.java index d6f5b00ed..9777f2153 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/ExpiryDateWidget.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/ExpiryDateWidget.java @@ -27,43 +27,55 @@ import android.text.TextUtils; import android.text.TextWatcher; import android.view.ContextThemeWrapper; +import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.EditText; -import android.widget.RelativeLayout; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.google.android.material.textfield.TextInputLayout; import com.hyperwallet.android.hyperwallet_ui.R; -import com.hyperwallet.android.model.meta.HyperwalletField; +import com.hyperwallet.android.model.meta.field.HyperwalletField; public class ExpiryDateWidget extends AbstractWidget { private ViewGroup mContainer; private final ExpireDateUtil mExpireDateUtil; private TextInputLayout mTextInputLayout; private String mValue; + private String mMessageInvalidDateLength; + private String mMessageInvalidDate; public ExpiryDateWidget(@NonNull HyperwalletField field, @NonNull WidgetEventListener listener, - @NonNull Context context, @Nullable String defaultValue, @NonNull View defaultFocusView) { - super(field, listener, context, defaultValue, defaultFocusView); + @Nullable String defaultValue, @NonNull View defaultFocusView) { + super(field, listener, defaultValue, defaultFocusView); mValue = defaultValue; mExpireDateUtil = new ExpireDateUtil(); } @Override - public View getView() { + public View getView(@NonNull final ViewGroup viewGroup) { if (mContainer == null) { - mContainer = new RelativeLayout(mContext); + mContainer = (ViewGroup) LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.item_widget_layout, viewGroup, false); + + // initialize messaging + mMessageInvalidDateLength = viewGroup.getContext().getResources() + .getString(R.string.error_exact_length_field, MAX_INPUT_LENGTH); + mMessageInvalidDate = viewGroup.getContext().getResources() + .getString(R.string.error_invalid_expiry_date, mField.getLabel()); // input control - mTextInputLayout = new TextInputLayout( - new ContextThemeWrapper(mContext, R.style.Widget_Hyperwallet_TextInputLayout)); + mTextInputLayout = new TextInputLayout(new ContextThemeWrapper(viewGroup.getContext(), + mField.isEditable() ? R.style.Widget_Hyperwallet_TextInputLayout + : R.style.Widget_Hyperwallet_TextInputLayout_Disabled)); final EditText editText = new EditText( - new ContextThemeWrapper(mContext, R.style.Widget_Hyperwallet_TextInputEditText)); + new ContextThemeWrapper(viewGroup.getContext(), R.style.Widget_Hyperwallet_TextInputEditText)); + + editText.setEnabled(mField.isEditable()); setIdFromFieldLabel(mTextInputLayout); setIdFromFieldName(editText); editText.setOnFocusChangeListener(new View.OnFocusChangeListener() { @@ -75,10 +87,10 @@ public void onFocusChange(View v, boolean hasFocus) { } else { mListener.widgetFocused(ExpiryDateWidget.this.getName()); editText.setHint(editText.getText().toString().trim().isEmpty() ? - mContext.getResources().getString(R.string.api_expiry_date_format) : ""); + viewGroup.getContext().getResources().getString(R.string.api_expiry_date_format) : ""); InputMethodManager imm = (InputMethodManager) - mContext.getSystemService(Context.INPUT_METHOD_SERVICE); + viewGroup.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT); } } @@ -170,8 +182,9 @@ public void afterTextChanged(Editable s) { editText.setInputType(InputType.TYPE_CLASS_DATETIME); editText.setHint(mField.getLabel()); - editText.setText(TextUtils.isEmpty(mDefaultValue) ? "" : - mExpireDateUtil.convertDateFromServerFormat(mDefaultValue)); + editText.setText(mExpireDateUtil.convertDateFromServerFormat( + TextUtils.isEmpty(mDefaultValue) ? mField.getValue() : mDefaultValue)); + editText.setOnKeyListener(new DefaultKeyListener(mDefaultFocusView, editText)); editText.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI | EditorInfo.IME_ACTION_NEXT); @@ -203,11 +216,11 @@ public String getErrorMessage() { } if (isInvalidLength()) { - return mContext.getResources().getString(R.string.error_exact_length_field, MAX_INPUT_LENGTH); + return mMessageInvalidDateLength; } if (mExpireDateUtil.isInvalidDate(mValue)) { - return mContext.getResources().getString(R.string.error_invalid_expiry_date, mField.getLabel()); + return mMessageInvalidDate; } return null; diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/NumberWidget.java b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/NumberWidget.java index cafa5e9c2..39dcc7eed 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/NumberWidget.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/NumberWidget.java @@ -16,45 +16,50 @@ */ package com.hyperwallet.android.ui.view.widget; -import android.content.Context; import android.text.Editable; import android.text.InputType; +import android.text.TextUtils; import android.text.TextWatcher; import android.view.ContextThemeWrapper; +import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import android.widget.EditText; -import android.widget.RelativeLayout; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.google.android.material.textfield.TextInputLayout; import com.hyperwallet.android.hyperwallet_ui.R; -import com.hyperwallet.android.model.meta.HyperwalletField; +import com.hyperwallet.android.model.meta.field.HyperwalletField; public class NumberWidget extends AbstractWidget { private ViewGroup mContainer; private TextInputLayout mTextInputLayout; - private String mValue = ""; + private String mValue; public NumberWidget(@NonNull HyperwalletField field, @NonNull WidgetEventListener listener, - @NonNull Context context, @Nullable String defaultValue, @NonNull View defaultFocusView) { - super(field, listener, context, defaultValue, defaultFocusView); + @Nullable String defaultValue, @NonNull View defaultFocusView) { + super(field, listener, defaultValue, defaultFocusView); mValue = defaultValue; } @Override - public View getView() { + public View getView(@NonNull final ViewGroup viewGroup) { if (mContainer == null) { - mContainer = new RelativeLayout(mContext); + mContainer = (ViewGroup) LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.item_widget_layout, viewGroup, false); + // number input text - mTextInputLayout = new TextInputLayout( - new ContextThemeWrapper(mContext, R.style.Widget_Hyperwallet_TextInputLayout)); + mTextInputLayout = new TextInputLayout(new ContextThemeWrapper(viewGroup.getContext(), + mField.isEditable() ? R.style.Widget_Hyperwallet_TextInputLayout + : R.style.Widget_Hyperwallet_TextInputLayout_Disabled)); mTextInputLayout.setHint(mField.getLabel()); + final EditText editText = new EditText( - new ContextThemeWrapper(mContext, R.style.Widget_Hyperwallet_TextInputEditText)); + new ContextThemeWrapper(viewGroup.getContext(), R.style.Widget_Hyperwallet_TextInputEditText)); + editText.setEnabled(mField.isEditable()); setIdFromFieldLabel(mTextInputLayout); setIdFromFieldName(editText); @@ -87,9 +92,9 @@ public void afterTextChanged(Editable s) { } }); + editText.setText(TextUtils.isEmpty(mDefaultValue) ? mField.getValue() : mDefaultValue); editText.setInputType(InputType.TYPE_CLASS_NUMBER); editText.setOnKeyListener(new DefaultKeyListener(mDefaultFocusView, editText)); - editText.setText(mDefaultValue); editText.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI | EditorInfo.IME_ACTION_NEXT); mTextInputLayout.addView(editText); appendLayout(mTextInputLayout, true); diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/PhoneWidget.java b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/PhoneWidget.java index 7bce341f7..f8254aaa1 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/PhoneWidget.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/PhoneWidget.java @@ -16,44 +16,50 @@ */ package com.hyperwallet.android.ui.view.widget; -import android.content.Context; import android.text.Editable; import android.text.InputType; +import android.text.TextUtils; import android.text.TextWatcher; import android.view.ContextThemeWrapper; +import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import android.widget.EditText; -import android.widget.RelativeLayout; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.google.android.material.textfield.TextInputLayout; import com.hyperwallet.android.hyperwallet_ui.R; -import com.hyperwallet.android.model.meta.HyperwalletField; +import com.hyperwallet.android.model.meta.field.HyperwalletField; public class PhoneWidget extends AbstractWidget { private ViewGroup mContainer; private String mValue = ""; private TextInputLayout mTextInputLayout; - public PhoneWidget(@NonNull HyperwalletField field, @NonNull WidgetEventListener listener, @NonNull Context context, + public PhoneWidget(@NonNull HyperwalletField field, @NonNull WidgetEventListener listener, @Nullable String defaultValue, @NonNull View defaultFocusView) { - super(field, listener, context, defaultValue, defaultFocusView); + super(field, listener, defaultValue, defaultFocusView); mValue = defaultValue; } @Override - public View getView() { + public View getView(@NonNull final ViewGroup viewGroup) { if (mContainer == null) { - mContainer = new RelativeLayout(mContext); - mTextInputLayout = new TextInputLayout( - new ContextThemeWrapper(mContext, R.style.Widget_Hyperwallet_TextInputLayout)); + mContainer = (ViewGroup) LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.item_widget_layout, viewGroup, false); + + mTextInputLayout = new TextInputLayout(new ContextThemeWrapper(viewGroup.getContext(), + mField.isEditable() ? R.style.Widget_Hyperwallet_TextInputLayout + : R.style.Widget_Hyperwallet_TextInputLayout_Disabled)); + // input control final EditText editText = new EditText( - new ContextThemeWrapper(mContext, R.style.Widget_Hyperwallet_TextInputEditText)); + new ContextThemeWrapper(viewGroup.getContext(), R.style.Widget_Hyperwallet_TextInputEditText)); + editText.setEnabled(mField.isEditable()); + mTextInputLayout.addView(editText); mTextInputLayout.setHint(mField.getLabel()); setIdFromFieldName(editText); @@ -87,10 +93,10 @@ public void afterTextChanged(Editable s) { } }); + editText.setText(TextUtils.isEmpty(mDefaultValue) ? mField.getValue() : mDefaultValue); editText.setInputType(InputType.TYPE_CLASS_PHONE); editText.setOnKeyListener(new DefaultKeyListener(mDefaultFocusView, editText)); editText.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI | EditorInfo.IME_ACTION_NEXT); - editText.setText(mDefaultValue); appendLayout(mTextInputLayout, true); mContainer.addView(mTextInputLayout); } diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/SelectionWidget.java b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/SelectionWidget.java index a9f34045a..146de1b65 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/SelectionWidget.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/SelectionWidget.java @@ -17,15 +17,14 @@ package com.hyperwallet.android.ui.view.widget; import android.app.Activity; -import android.content.Context; import android.text.TextUtils; import android.view.ContextThemeWrapper; +import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.EditText; -import android.widget.RelativeLayout; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -33,11 +32,10 @@ import com.google.android.material.textfield.TextInputLayout; import com.hyperwallet.android.hyperwallet_ui.R; -import com.hyperwallet.android.model.meta.HyperwalletField; -import com.hyperwallet.android.model.meta.HyperwalletFieldSelectionOption; +import com.hyperwallet.android.model.meta.field.HyperwalletField; +import com.hyperwallet.android.model.meta.field.HyperwalletFieldSelectionOption; import com.hyperwallet.android.ui.view.WidgetSelectionDialogFragment; -import java.util.Locale; import java.util.Set; import java.util.TreeMap; @@ -50,41 +48,43 @@ public class SelectionWidget extends AbstractWidget implements WidgetSelectionDi private String mValue; public SelectionWidget(@NonNull HyperwalletField field, @NonNull WidgetEventListener listener, - @NonNull Context context, @Nullable String defaultValue, @NonNull View defaultFocusView) { - super(field, listener, context, defaultValue, defaultFocusView); + @Nullable String defaultValue, @NonNull View defaultFocusView) { + super(field, listener, defaultValue, defaultFocusView); mValue = defaultValue; mSelectionNameValueMap = new TreeMap<>(); - for (HyperwalletFieldSelectionOption option : field.getFieldSelectionOptions()) { - if (!TextUtils.isEmpty(option.getLabel())) { - String label = option.getLabel().substring(1).toLowerCase(Locale.ROOT); - label = option.getLabel().substring(0, 1) + label; - mSelectionNameValueMap.put(label, option.getValue()); + if (field.getFieldSelectionOptions() != null) { + for (HyperwalletFieldSelectionOption option : field.getFieldSelectionOptions()) { + if (!TextUtils.isEmpty(option.getLabel())) { + mSelectionNameValueMap.put(option.getLabel(), option.getValue()); + } } } } @Override - public View getView() { + public View getView(@NonNull final ViewGroup viewGroup) { if (mContainer == null) { - mContainer = new RelativeLayout(mContext); + mContainer = (ViewGroup) LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.item_widget_layout, viewGroup, false); + setIdFromFieldLabel(mContainer); mContainer.setFocusable(true); mContainer.setFocusableInTouchMode(true); - mTextInputLayout = new TextInputLayout( - new ContextThemeWrapper(mContext, R.style.Widget_Hyperwallet_TextInputLayout)); + mTextInputLayout = new TextInputLayout(new ContextThemeWrapper(viewGroup.getContext(), + mField.isEditable() ? R.style.Widget_Hyperwallet_TextInputLayout + : R.style.Widget_Hyperwallet_TextInputLayout_Disabled)); mEditText = new EditText( - new ContextThemeWrapper(mContext, R.style.Widget_Hyperwallet_TextInputEditText)); - if (!TextUtils.isEmpty(mDefaultValue)) { - mEditText.setText(getKeyFromValue(mDefaultValue)); - } + new ContextThemeWrapper(viewGroup.getContext(), R.style.Widget_Hyperwallet_TextInputEditText)); + mEditText.setText( + getKeyFromValue(TextUtils.isEmpty(mDefaultValue) ? mValue = mField.getValue() : mDefaultValue)); setIdFromFieldLabel(mTextInputLayout); setIdFromFieldName(mEditText); mEditText.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI); mEditText.setKeyListener(null); mEditText.setCompoundDrawablesWithIntrinsicBounds(null, null, - ContextCompat.getDrawable(mContext, R.drawable.ic_keyboard_arrow_down_12dp), null); + ContextCompat.getDrawable(viewGroup.getContext(), R.drawable.ic_keyboard_arrow_down_12dp), null); mEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override @@ -104,13 +104,17 @@ public void onFocusChange(View v, boolean hasFocus) { } }); - mEditText.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - hideSoftKey(v); - showSelectionFragmentDialog(); - } - }); + if (mField.isEditable()) { + mEditText.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + hideSoftKey(v); + showSelectionFragmentDialog(); + } + }); + } else { + mEditText.setEnabled(false); + } mTextInputLayout.setHint(mField.getLabel()); mTextInputLayout.addView(mEditText); @@ -145,7 +149,8 @@ private void hideSoftKey(@NonNull View focusedView) { private void showSelectionFragmentDialog() { String defaultSelected = TextUtils.isEmpty(mValue) ? - TextUtils.isEmpty(mDefaultValue) ? "" : getKeyFromValue(mDefaultValue) : getKeyFromValue(mValue); + TextUtils.isEmpty(mDefaultValue) ? getKeyFromValue(mField.getValue()) : + getKeyFromValue(mDefaultValue) : getKeyFromValue(mValue); mListener.openWidgetSelectionFragmentDialog(mSelectionNameValueMap, defaultSelected, mField.getLabel(), mField.getName()); } diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/TextWidget.java b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/TextWidget.java index fb8e322ec..f16fd51c0 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/TextWidget.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/TextWidget.java @@ -16,46 +16,51 @@ */ package com.hyperwallet.android.ui.view.widget; -import android.content.Context; import android.text.Editable; import android.text.InputType; +import android.text.TextUtils; import android.text.TextWatcher; import android.view.ContextThemeWrapper; +import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; import android.widget.EditText; -import android.widget.RelativeLayout; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.google.android.material.textfield.TextInputLayout; import com.hyperwallet.android.hyperwallet_ui.R; -import com.hyperwallet.android.model.meta.HyperwalletField; +import com.hyperwallet.android.model.meta.field.HyperwalletField; public class TextWidget extends AbstractWidget { private ViewGroup mContainer; - private String mValue = ""; + private String mValue; private TextInputLayout mTextInputLayout; - public TextWidget(@NonNull HyperwalletField field, @NonNull WidgetEventListener listener, @NonNull Context context, + public TextWidget(@NonNull HyperwalletField field, @NonNull WidgetEventListener listener, @Nullable String defaultValue, @NonNull View defaultFocusView) { - super(field, listener, context, defaultValue, defaultFocusView); + super(field, listener, defaultValue, defaultFocusView); mValue = defaultValue; } @Override - public View getView() { + public View getView(@NonNull final ViewGroup viewGroup) { if (mContainer == null) { - mContainer = new RelativeLayout(mContext); + mContainer = (ViewGroup) LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.item_widget_layout, viewGroup, false); mContainer.setTag(mField.getName()); - mTextInputLayout = new TextInputLayout( - new ContextThemeWrapper(mContext, R.style.Widget_Hyperwallet_TextInputLayout)); + + mTextInputLayout = new TextInputLayout(new ContextThemeWrapper(viewGroup.getContext(), + mField.isEditable() ? R.style.Widget_Hyperwallet_TextInputLayout + : R.style.Widget_Hyperwallet_TextInputLayout_Disabled)); + final EditText editText = new EditText( - new ContextThemeWrapper(mContext, R.style.Widget_Hyperwallet_TextInputEditText)); - mTextInputLayout.setHint(mField.getLabel()); + new ContextThemeWrapper(viewGroup.getContext(), R.style.Widget_Hyperwallet_TextInputEditText)); + editText.setEnabled(mField.isEditable()); + mTextInputLayout.setHint(mField.getLabel()); setIdFromFieldLabel(mTextInputLayout); setIdFromFieldName(editText); editText.setOnFocusChangeListener(new View.OnFocusChangeListener() { @@ -87,10 +92,10 @@ public void afterTextChanged(Editable s) { } }); + editText.setText(TextUtils.isEmpty(mDefaultValue) ? mField.getValue() : mDefaultValue); editText.setInputType(InputType.TYPE_CLASS_TEXT); editText.setOnKeyListener(new DefaultKeyListener(mDefaultFocusView, editText)); editText.setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI | EditorInfo.IME_ACTION_NEXT); - editText.setText(mDefaultValue); mTextInputLayout.addView(editText); appendLayout(mTextInputLayout, true); diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/WidgetFactory.java b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/WidgetFactory.java index 405cd2df9..18bd507ca 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/WidgetFactory.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/WidgetFactory.java @@ -16,22 +16,20 @@ */ package com.hyperwallet.android.ui.view.widget; -import android.content.Context; import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.hyperwallet.android.exception.HyperwalletException; -import com.hyperwallet.android.model.meta.EDataType; -import com.hyperwallet.android.model.meta.HyperwalletField; +import com.hyperwallet.android.model.meta.field.EDataType; +import com.hyperwallet.android.model.meta.field.HyperwalletField; import java.lang.reflect.InvocationTargetException; import java.util.HashMap; public class WidgetFactory { - private static final String TAG = AbstractWidget.class.getName(); private static final HashMap WIDGET_MAP_DEFINITION = new HashMap() {{ put(EDataType.TEXT, TextWidget.class); put(EDataType.SELECTION, SelectionWidget.class); @@ -43,18 +41,17 @@ public class WidgetFactory { @SuppressWarnings("unchecked") public static AbstractWidget newWidget(@NonNull HyperwalletField field, @NonNull WidgetEventListener listener, - @NonNull Context context, @Nullable String defaultValue, @NonNull View view) throws HyperwalletException { + @Nullable String defaultValue, @NonNull View view) throws HyperwalletException { try { if (WIDGET_MAP_DEFINITION.containsKey(field.getDataType())) { return (AbstractWidget) WIDGET_MAP_DEFINITION.get(field.getDataType()) - .getConstructor(HyperwalletField.class, WidgetEventListener.class, - Context.class, String.class, View.class) - .newInstance(field, listener, context, defaultValue, view); + .getConstructor(HyperwalletField.class, WidgetEventListener.class, String.class, View.class) + .newInstance(field, listener, defaultValue, view); } } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException e) { throw new HyperwalletException(e); } - return new TextWidget(field, listener, context, defaultValue, view); + return new TextWidget(field, listener, defaultValue, view); } } diff --git a/ui/src/main/res/layout/fragment_add_transfer_method.xml b/ui/src/main/res/layout/fragment_add_transfer_method.xml index d7d00c13d..861e1bdcd 100644 --- a/ui/src/main/res/layout/fragment_add_transfer_method.xml +++ b/ui/src/main/res/layout/fragment_add_transfer_method.xml @@ -36,21 +36,6 @@ android:layout_height="wrap_content" android:orientation="vertical"> - - - - - + \ No newline at end of file diff --git a/ui/src/main/res/layout/item_widget_section_header.xml b/ui/src/main/res/layout/item_widget_section_header.xml new file mode 100644 index 000000000..10e63e4ab --- /dev/null +++ b/ui/src/main/res/layout/item_widget_section_header.xml @@ -0,0 +1,15 @@ + + + + diff --git a/ui/src/main/res/menu/menu_widget_selection.xml b/ui/src/main/res/menu/menu_widget_selection.xml new file mode 100644 index 000000000..41b5f332e --- /dev/null +++ b/ui/src/main/res/menu/menu_widget_selection.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/ui/src/main/res/values/dimens.xml b/ui/src/main/res/values/dimens.xml index af96abda6..1a3f3fb32 100644 --- a/ui/src/main/res/values/dimens.xml +++ b/ui/src/main/res/values/dimens.xml @@ -47,6 +47,10 @@ 32dp 330dp + + 8dp + 12dp + 136dp 1dp diff --git a/ui/src/main/res/values/ids.xml b/ui/src/main/res/values/ids.xml index df6202824..ed5803f80 100644 --- a/ui/src/main/res/values/ids.xml +++ b/ui/src/main/res/values/ids.xml @@ -14,4 +14,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ui/src/main/res/values/strings.xml b/ui/src/main/res/values/strings.xml index 7e43ad98f..0d68918e8 100644 --- a/ui/src/main/res/values/strings.xml +++ b/ui/src/main/res/values/strings.xml @@ -81,9 +81,17 @@ \uE00A \uE021 + Account Holder + Account Information + Address + Contact Information + Identification + Intermediary Account + Search Hint Search Country Search Currency + Search Account Information - %s (%s) Transfer Method Information diff --git a/ui/src/main/res/values/styles.xml b/ui/src/main/res/values/styles.xml index b61828efc..887a6de77 100644 --- a/ui/src/main/res/values/styles.xml +++ b/ui/src/main/res/values/styles.xml @@ -106,6 +106,10 @@ @color/colorSecondaryDark + + + + + + diff --git a/ui/src/test/java/com/hyperwallet/android/ui/view/widget/DateUtilTest.java b/ui/src/test/java/com/hyperwallet/android/ui/view/widget/DateUtilTest.java index 7452c2d14..801ce6851 100644 --- a/ui/src/test/java/com/hyperwallet/android/ui/view/widget/DateUtilTest.java +++ b/ui/src/test/java/com/hyperwallet/android/ui/view/widget/DateUtilTest.java @@ -10,53 +10,63 @@ import java.util.Arrays; import java.util.Calendar; import java.util.Collection; +import java.util.List; @RunWith(RobolectricTestRunner.class) public class DateUtilTest { private final DateUtil mDateUtil = new DateUtil(); + @Test - public void testParseDateFromServerToWidget() { - String serverDate; - String widgetDate; - Collection inputParamList = buildParamsDateFromServerToWidget(); - for (Object[] item : inputParamList) { - serverDate = (String) item[0]; - widgetDate = (String) item[1]; - assertThat(mDateUtil.convertDateFromServerToWidgetFormat(serverDate), is(widgetDate)); + public void testParseIncorrectDateFromServerToWidget() throws Exception { + final List inputParamList = buildParamsDateFromServerToWidget(); + for (String serverDate : inputParamList) { + boolean isIncorrect = false; + try { + mDateUtil.convertDateFromServerToWidgetFormat(serverDate); + } catch (DateParseException e) { + isIncorrect = true; + } + assertThat(isIncorrect, is(true)); } } @Test - public void testParseDateFromServerToCalendar() { - String serverDate; - Calendar widgetDate; - Collection inputParamList = buildParamsDateFromServerToCalendar(); - for (Object[] item : inputParamList) { - serverDate = (String) item[0]; - widgetDate = (Calendar) item[1]; - assertThat(mDateUtil.convertDateFromServerFormatToCalendar(serverDate).getTime().toString(), - is(widgetDate.getTime().toString())); - } + public void testParseCorrectDateFromServerToWidget() throws Exception { + String serverDate = "2005-05-23"; + String widgetDate = "23 May 2005"; + assertThat(mDateUtil.convertDateFromServerToWidgetFormat(serverDate), is(widgetDate)); + assertThat(mDateUtil.convertDateFromServerToWidgetFormat(""), is("")); + assertThat(mDateUtil.convertDateFromServerToWidgetFormat(null), is("")); } - @Test - public void testParseDateFromDialogToWidgetFormat() { - String widgetDate; - int year; - int month; - int dayOfMonth; - Collection inputParamList = buildParamsFromDialogToWidget(); - for (Object[] item : inputParamList) { - year = (int) item[0]; - month = (int) item[1]; - dayOfMonth = (int) item[2]; - widgetDate = (String) item[3]; - assertThat(mDateUtil.buildDateFromDateDialogToWidgetFormat(year, month, dayOfMonth), is(widgetDate)); + public void testParseIncorrectDateFromServerToCalendar() throws Exception { + List inputParamList = buildParamsDateFromServerToCalendar(); + for (String serverDate : inputParamList) { + boolean isIncorrect = false; + try { + mDateUtil.convertDateFromServerFormatToCalendar(serverDate).getTime(); + } catch (DateParseException e) { + isIncorrect = true; + } + assertThat(isIncorrect, is(true)); } } + @Test + public void testParseCorrectDateFromServerToCalendar() throws DateParseException { + assertThat(mDateUtil.convertDateFromServerFormatToCalendar(null).getTime().toString(), + is(Calendar.getInstance().getTime().toString())); + assertThat(mDateUtil.convertDateFromServerFormatToCalendar("").getTime().toString(), + is(Calendar.getInstance().getTime().toString())); + String serverDate = "2005-05-23"; + final Calendar mayCalendar = Calendar.getInstance(); + mayCalendar.set(2005, 4, 23, 0, 0, 0); + assertThat(mDateUtil.convertDateFromServerFormatToCalendar(serverDate).getTime().toString(), + is(mayCalendar.getTime().toString())); + } + @Test public void testParseDateFromDialogToServerFormat() { String widgetDate; @@ -73,48 +83,32 @@ public void testParseDateFromDialogToServerFormat() { } } - private Collection buildParamsDateFromServerToWidget() { - return Arrays.asList(new Object[][]{ - {null, ""}, - {"", ""}, - {"0", ""}, - {"1990-01", ""}, - {"1990-03-111", ""}, - {"10-20-1", ""}, - {"2190-13-1", ""}, - {"2190-00-1", ""}, - {"2190-01-00", ""}, - {"2190-01-0", ""}, - {"2190-01-32", ""}, - {"2005-05-23", "23 May 2005"} - }); + private List buildParamsDateFromServerToWidget() { + return Arrays.asList( + "0", + "1990-01", + "1990-03-111", + "10-20-1", + "2190-13-1", + "2190-00-1", + "2190-01-00", + "2190-01-0", + "2190-01-32" + ); } - private Collection buildParamsDateFromServerToCalendar() { - final Calendar mayCalendar = Calendar.getInstance(); - mayCalendar.set(2005, 4, 23, 0, 0, 0); - return Arrays.asList(new Object[][]{ - {null, Calendar.getInstance()}, - {"", Calendar.getInstance()}, - {"0", Calendar.getInstance()}, - {"1990-01", Calendar.getInstance()}, - {"1990-03-111", Calendar.getInstance()}, - {"10-20-1", Calendar.getInstance()}, - {"19-1102-1", Calendar.getInstance()}, - {"2190-13-1", Calendar.getInstance()}, - {"2190-00-1", Calendar.getInstance()}, - {"2190-01-00", Calendar.getInstance()}, - {"2190-01-0", Calendar.getInstance()}, - {"2005-05-23", mayCalendar} - }); - } - - - private Collection buildParamsFromDialogToWidget() { - return Arrays.asList(new Object[][]{ - {1900, 0, 1, "01 January 1900"}, - {2001, 10, 13, "13 November 2001"} - }); + private List buildParamsDateFromServerToCalendar() { + return Arrays.asList( + "0", + "1990-01", + "1990-03-111", + "10-20-1", + "19-1102-1", + "2190-13-1", + "2190-00-1", + "2190-01-00", + "2190-01-0" + ); } private Collection buildParamsFromDialogToServer() { From d08561e5b0d7f44e18bade51413df3879de05e2a Mon Sep 17 00:00:00 2001 From: azakrevska-epam Date: Thu, 23 May 2019 20:21:13 +0300 Subject: [PATCH 5/8] HW-52174. Moved dialog to the fragment --- .../AddTransferMethodActivity.java | 20 ++- .../AddTransferMethodFragment.java | 44 ++----- .../ui/view/widget/DateDialogFragment.java | 118 ++++++++++++++++++ .../android/ui/view/widget/DateWidget.java | 26 ++-- .../ui/view/widget/WidgetEventListener.java | 4 +- 5 files changed, 158 insertions(+), 54 deletions(-) create mode 100644 ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateDialogFragment.java diff --git a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodActivity.java b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodActivity.java index c9ef23a90..bba9c9f3c 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodActivity.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodActivity.java @@ -21,6 +21,7 @@ import android.view.WindowManager; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import androidx.core.content.ContextCompat; @@ -33,6 +34,7 @@ import com.hyperwallet.android.ui.view.WidgetSelectionDialogFragment; import com.hyperwallet.android.ui.view.error.DefaultErrorDialogFragment; import com.hyperwallet.android.ui.view.error.OnNetworkErrorCallback; +import com.hyperwallet.android.ui.view.widget.DateDialogFragment; import java.util.List; @@ -40,7 +42,8 @@ public class AddTransferMethodActivity extends AppCompatActivity implements WidgetSelectionDialogFragment.WidgetSelectionItemListener, AddTransferMethodFragment.OnAddTransferMethodNetworkErrorCallback, AddTransferMethodFragment.OnLoadTransferMethodConfigurationFieldsNetworkErrorCallback, - OnNetworkErrorCallback, AddTransferMethodFragment.OnSelectedDateCallback { + OnNetworkErrorCallback, AddTransferMethodFragment.OnShowDateDialogCallback, + DateDialogFragment.OnSelectedDateCallback { public static final String EXTRA_TRANSFER_METHOD_COUNTRY = "TRANSFER_METHOD_COUNTRY"; public static final String EXTRA_TRANSFER_METHOD_CURRENCY = "TRANSFER_METHOD_CURRENCY"; @@ -191,6 +194,21 @@ private AddTransferMethodFragment getAddTransferMethodFragment() { return fragment; } + @Override + public void showDateDialog(@Nullable final String date, @NonNull final String fieldName) { + FragmentManager fragmentManager = getSupportFragmentManager(); + DateDialogFragment fragment = (DateDialogFragment) + fragmentManager.findFragmentByTag(DateDialogFragment.TAG); + + if (fragment == null) { + fragment = DateDialogFragment.newInstance(date, fieldName); + } + + if (!fragment.isAdded()) { + fragment.show(fragmentManager); + } + } + @Override public void setSelectedDateField(@NonNull String fieldName, final String selectedValue) { FragmentManager fragmentManager = getSupportFragmentManager(); diff --git a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodFragment.java b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodFragment.java index 9aba7f1aa..a9691033c 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodFragment.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodFragment.java @@ -25,9 +25,7 @@ import static com.hyperwallet.android.model.HyperwalletTransferMethod.TransferMethodTypes.PAYPAL_ACCOUNT; import android.app.Activity; -import android.app.DatePickerDialog; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.text.TextUtils; @@ -36,7 +34,6 @@ import android.view.ViewGroup; import android.view.WindowManager; import android.widget.Button; -import android.widget.DatePicker; import android.widget.RelativeLayout; import android.widget.TextView; @@ -93,7 +90,7 @@ public class AddTransferMethodFragment extends Fragment implements WidgetEventLi private OnAddTransferMethodNetworkErrorCallback mOnAddTransferMethodNetworkErrorCallback; private OnLoadTransferMethodConfigurationFieldsNetworkErrorCallback mOnLoadTransferMethodConfigurationFieldsNetworkErrorCallback; - private OnSelectedDateCallback mOnSelectedDateCallback; + private OnShowDateDialogCallback mOnShowDateDialogCallback; private AddTransferMethodContract.Presenter mPresenter; private View mProgressBar; private boolean mShowCreateProgressBar; @@ -166,11 +163,10 @@ public void onAttach(Context context) { } try { - mOnSelectedDateCallback = - (OnSelectedDateCallback) context; + mOnShowDateDialogCallback = (OnShowDateDialogCallback) context; } catch (ClassCastException e) { throw new ClassCastException(getActivity().toString() + " must implement " - + OnSelectedDateCallback.class.getCanonicalName()); + + OnShowDateDialogCallback.class.getCanonicalName()); } } @@ -501,8 +497,8 @@ interface OnAddTransferMethodNetworkErrorCallback { void showErrorsAddTransferMethod(@NonNull final List errors); } - interface OnSelectedDateCallback { - void setSelectedDateField(@NonNull final String fieldName, final String selectedValue); + interface OnShowDateDialogCallback { + void showDateDialog(@Nullable final String date, @NonNull final String fieldName); } private void triggerSubmit() { @@ -602,35 +598,11 @@ public boolean isActive() { } @Override - public void openWidgetDateDialog(final int year, final int month, final int dayOfMonth, - @NonNull final String fieldName) { - DatePickerDialog datePickerDialog = new DatePickerDialog(requireContext(), - R.style.Widget_Hyperwallet_DatePicker, - new DatePickerDialog.OnDateSetListener() { - @Override - public void onDateSet(DatePicker view, int resultYear, int resultMonth, int resultDayOfMonth) { - final String selectedDate = mDateUtil - .buildDateFromDateDialogToServerFormat(resultYear, resultMonth, resultDayOfMonth); - mOnSelectedDateCallback.setSelectedDateField(fieldName, selectedDate); - } - }, - year, month, dayOfMonth); - - datePickerDialog.setButton(DialogInterface.BUTTON_NEGATIVE, - getString(R.string.cancel_button_label), - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - if (which == DialogInterface.BUTTON_NEGATIVE) { - mOnSelectedDateCallback.setSelectedDateField(fieldName, null); - } - } - }); - - datePickerDialog.show(); + public void openWidgetDateDialog(@Nullable final String date, @NonNull final String fieldName) { + mOnShowDateDialogCallback.showDateDialog(date, fieldName); } - protected void onDateSelected(@NonNull final String selectedValue, @NonNull final String fieldName) { + void onDateSelected(@NonNull final String selectedValue, @NonNull final String fieldName) { for (int i = 0; i < mDynamicContainer.getChildCount(); i++) { View view = mDynamicContainer.getChildAt(i); if (view.getTag() instanceof DateWidget) { diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateDialogFragment.java b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateDialogFragment.java new file mode 100644 index 000000000..8b1c9b8d2 --- /dev/null +++ b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateDialogFragment.java @@ -0,0 +1,118 @@ +package com.hyperwallet.android.ui.view.widget; + +import android.app.DatePickerDialog; +import android.app.Dialog; +import android.content.Context; +import android.content.DialogInterface; +import android.os.Bundle; +import android.widget.DatePicker; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; + +import com.hyperwallet.android.hyperwallet_ui.R; + +import java.util.Calendar; + +public class DateDialogFragment extends DialogFragment { + + public static final String TAG = DateDialogFragment.class.getName(); + private static final String ARGUMENT_DATE = "ARGUMENT_DATE"; + private static final String ARGUMENT_FIELD_NAME = "ARGUMENT_FIELD_NAME"; + private OnSelectedDateCallback mOnSelectedDateCallback; + private DateUtil mDateUtil; + + /** + * Please do not use this to have instance of DateDialogFragment this is reserved for android framework + */ + public DateDialogFragment() { + setRetainInstance(true); + } + + public static DateDialogFragment newInstance(final String date, @NonNull final String fieldName) { + DateDialogFragment dateDialogFragment = new DateDialogFragment(); + Bundle bundle = new Bundle(); + bundle.putString(ARGUMENT_DATE, date); + bundle.putString(ARGUMENT_FIELD_NAME, fieldName); + dateDialogFragment.setArguments(bundle); + + return dateDialogFragment; + } + + @Override + public void onAttach(Context context) { + super.onAttach(context); + try { + mOnSelectedDateCallback = (OnSelectedDateCallback) context; + } catch (ClassCastException e) { + throw new ClassCastException(getActivity().toString() + + " must implement " + + OnSelectedDateCallback.class.getCanonicalName()); + } + } + + public void show(@NonNull FragmentManager manager) { + show(manager, TAG); + } + + @Override + public void onDestroyView() { + Dialog dialog = getDialog(); + if (dialog != null && getRetainInstance()) { + dialog.setDismissMessage(null); + } + super.onDestroyView(); + } + + @NonNull + @Override + public Dialog onCreateDialog(@Nullable Bundle state) { + + String storedDate = getArguments() != null ? getArguments().getString(ARGUMENT_DATE) : ""; + final String fieldName = getArguments().getString(ARGUMENT_FIELD_NAME); + Calendar calendar; + try { + calendar = getDateUtil().convertDateFromServerFormatToCalendar(storedDate); + } catch (DateParseException e) { + calendar = Calendar.getInstance(); + } + + DatePickerDialog datePickerDialog = new DatePickerDialog(requireContext(), + R.style.Widget_Hyperwallet_DatePicker, + new DatePickerDialog.OnDateSetListener() { + @Override + public void onDateSet(DatePicker view, int resultYear, int resultMonth, int resultDayOfMonth) { + final String selectedDate = getDateUtil() + .buildDateFromDateDialogToServerFormat(resultYear, resultMonth, resultDayOfMonth); + mOnSelectedDateCallback.setSelectedDateField(fieldName, selectedDate); + } + }, + calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH)); + + datePickerDialog.setButton(DialogInterface.BUTTON_NEGATIVE, + getString(R.string.cancel_button_label), + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + if (which == DialogInterface.BUTTON_NEGATIVE) { + mOnSelectedDateCallback.setSelectedDateField(fieldName, null); + } + } + }); + + return datePickerDialog; + } + + private DateUtil getDateUtil() { + if (mDateUtil == null) { + mDateUtil = new DateUtil(); + } + return mDateUtil; + } + + public interface OnSelectedDateCallback { + void setSelectedDateField(@NonNull final String fieldName, final String selectedValue); + } +} diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateWidget.java b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateWidget.java index 469a66783..b58e00a24 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateWidget.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateWidget.java @@ -16,12 +16,14 @@ */ package com.hyperwallet.android.ui.view.widget; +import android.app.Activity; import android.text.TextUtils; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodManager; import android.widget.EditText; import androidx.annotation.NonNull; @@ -31,8 +33,6 @@ import com.hyperwallet.android.hyperwallet_ui.R; import com.hyperwallet.android.model.meta.field.HyperwalletField; -import java.util.Calendar; - public class DateWidget extends AbstractWidget implements DateChangedListener { private final DateUtil mDateUtil; @@ -85,7 +85,8 @@ public View getView(@NonNull final ViewGroup viewGroup) { mEditText.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - showDateSelectDialog(); + hideSoftKey(v); + mListener.openWidgetDateDialog(mValue, mField.getName()); } }); } @@ -106,18 +107,6 @@ public void showValidationError(String errorMessage) { mTextInputLayout.setError(errorMessage); } - private void showDateSelectDialog() { - - Calendar calendar = null; - try { - calendar = mDateUtil.convertDateFromServerFormatToCalendar(mValue); - } catch (DateParseException e) { - calendar = Calendar.getInstance(); - } - mListener.openWidgetDateDialog(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), - calendar.get(Calendar.DAY_OF_MONTH), mField.getName()); - } - @Override public void onUpdate(@Nullable final String selectedDate) { if (!TextUtils.isEmpty(selectedDate)) { @@ -134,4 +123,11 @@ public void onUpdate(@Nullable final String selectedDate) { mTextInputLayout.setError(null); } } + + private void hideSoftKey(@NonNull View focusedView) { + InputMethodManager inputMethodManager = (InputMethodManager) focusedView.getContext().getSystemService( + Activity.INPUT_METHOD_SERVICE); + inputMethodManager.hideSoftInputFromWindow(focusedView.getWindowToken(), 0); + } + } \ No newline at end of file diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/WidgetEventListener.java b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/WidgetEventListener.java index ed2d3ee4e..75ebe7535 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/WidgetEventListener.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/WidgetEventListener.java @@ -17,6 +17,7 @@ package com.hyperwallet.android.ui.view.widget; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import java.util.TreeMap; @@ -31,6 +32,5 @@ void openWidgetSelectionFragmentDialog(@NonNull final TreeMap na void saveTextChanged(@NonNull final String fieldName, @NonNull final String value); - void openWidgetDateDialog(final int year, final int month, final int dayOfMonth, - @NonNull final String fieldName); + void openWidgetDateDialog(@Nullable final String date, @NonNull final String fieldName); } From 7510bbd0503681f685d68422c17d421f1d14c832 Mon Sep 17 00:00:00 2001 From: azakrevska-epam Date: Thu, 23 May 2019 20:48:30 +0300 Subject: [PATCH 6/8] HW-52174. Moved date fragment outside of widget --- .../AddTransferMethodActivity.java | 10 +++++----- ...ment.java => WidgetDateDialogFragment.java} | 18 ++++++++++-------- .../android/ui/view/widget/DateUtil.java | 2 +- 3 files changed, 16 insertions(+), 14 deletions(-) rename ui/src/main/java/com/hyperwallet/android/ui/view/{widget/DateDialogFragment.java => WidgetDateDialogFragment.java} (85%) diff --git a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodActivity.java b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodActivity.java index bba9c9f3c..f195af509 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodActivity.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodActivity.java @@ -31,10 +31,10 @@ import com.hyperwallet.android.hyperwallet_ui.R; import com.hyperwallet.android.model.HyperwalletError; +import com.hyperwallet.android.ui.view.WidgetDateDialogFragment; import com.hyperwallet.android.ui.view.WidgetSelectionDialogFragment; import com.hyperwallet.android.ui.view.error.DefaultErrorDialogFragment; import com.hyperwallet.android.ui.view.error.OnNetworkErrorCallback; -import com.hyperwallet.android.ui.view.widget.DateDialogFragment; import java.util.List; @@ -43,7 +43,7 @@ public class AddTransferMethodActivity extends AppCompatActivity implements AddTransferMethodFragment.OnAddTransferMethodNetworkErrorCallback, AddTransferMethodFragment.OnLoadTransferMethodConfigurationFieldsNetworkErrorCallback, OnNetworkErrorCallback, AddTransferMethodFragment.OnShowDateDialogCallback, - DateDialogFragment.OnSelectedDateCallback { + WidgetDateDialogFragment.OnSelectedDateCallback { public static final String EXTRA_TRANSFER_METHOD_COUNTRY = "TRANSFER_METHOD_COUNTRY"; public static final String EXTRA_TRANSFER_METHOD_CURRENCY = "TRANSFER_METHOD_CURRENCY"; @@ -197,11 +197,11 @@ private AddTransferMethodFragment getAddTransferMethodFragment() { @Override public void showDateDialog(@Nullable final String date, @NonNull final String fieldName) { FragmentManager fragmentManager = getSupportFragmentManager(); - DateDialogFragment fragment = (DateDialogFragment) - fragmentManager.findFragmentByTag(DateDialogFragment.TAG); + WidgetDateDialogFragment fragment = (WidgetDateDialogFragment) + fragmentManager.findFragmentByTag(WidgetDateDialogFragment.TAG); if (fragment == null) { - fragment = DateDialogFragment.newInstance(date, fieldName); + fragment = WidgetDateDialogFragment.newInstance(date, fieldName); } if (!fragment.isAdded()) { diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateDialogFragment.java b/ui/src/main/java/com/hyperwallet/android/ui/view/WidgetDateDialogFragment.java similarity index 85% rename from ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateDialogFragment.java rename to ui/src/main/java/com/hyperwallet/android/ui/view/WidgetDateDialogFragment.java index 8b1c9b8d2..6897467ef 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateDialogFragment.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/view/WidgetDateDialogFragment.java @@ -1,4 +1,4 @@ -package com.hyperwallet.android.ui.view.widget; +package com.hyperwallet.android.ui.view; import android.app.DatePickerDialog; import android.app.Dialog; @@ -13,12 +13,14 @@ import androidx.fragment.app.FragmentManager; import com.hyperwallet.android.hyperwallet_ui.R; +import com.hyperwallet.android.ui.view.widget.DateParseException; +import com.hyperwallet.android.ui.view.widget.DateUtil; import java.util.Calendar; -public class DateDialogFragment extends DialogFragment { +public class WidgetDateDialogFragment extends DialogFragment { - public static final String TAG = DateDialogFragment.class.getName(); + public static final String TAG = WidgetDateDialogFragment.class.getName(); private static final String ARGUMENT_DATE = "ARGUMENT_DATE"; private static final String ARGUMENT_FIELD_NAME = "ARGUMENT_FIELD_NAME"; private OnSelectedDateCallback mOnSelectedDateCallback; @@ -27,18 +29,18 @@ public class DateDialogFragment extends DialogFragment { /** * Please do not use this to have instance of DateDialogFragment this is reserved for android framework */ - public DateDialogFragment() { + public WidgetDateDialogFragment() { setRetainInstance(true); } - public static DateDialogFragment newInstance(final String date, @NonNull final String fieldName) { - DateDialogFragment dateDialogFragment = new DateDialogFragment(); + public static WidgetDateDialogFragment newInstance(final String date, @NonNull final String fieldName) { + WidgetDateDialogFragment widgetDateDialogFragment = new WidgetDateDialogFragment(); Bundle bundle = new Bundle(); bundle.putString(ARGUMENT_DATE, date); bundle.putString(ARGUMENT_FIELD_NAME, fieldName); - dateDialogFragment.setArguments(bundle); + widgetDateDialogFragment.setArguments(bundle); - return dateDialogFragment; + return widgetDateDialogFragment; } @Override diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateUtil.java b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateUtil.java index 31c8b4edf..6e6c15d9b 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateUtil.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateUtil.java @@ -90,7 +90,7 @@ public String buildDateFromDateDialogToServerFormat(final int year, final int mo * @throws DateParseException unable to convert server date to calendar format */ @NonNull - Calendar convertDateFromServerFormatToCalendar(@Nullable final String serverDate) throws DateParseException { + public Calendar convertDateFromServerFormatToCalendar(@Nullable final String serverDate) throws DateParseException { final Calendar calendar = Calendar.getInstance(); try { if (isServerDateValid(serverDate)) { From 22f9f801a8e07a4825d45f312a946242c9877c2d Mon Sep 17 00:00:00 2001 From: azakrevska-epam Date: Thu, 23 May 2019 21:36:32 +0300 Subject: [PATCH 7/8] HW-52174. Moved call of date fragment inside of add fragment --- .../AddTransferMethodActivity.java | 19 +------------- .../AddTransferMethodFragment.java | 26 +++++++++---------- .../ui/view/WidgetDateDialogFragment.java | 17 ++++-------- .../ui/view/widget/DateParseException.java | 2 +- 4 files changed, 20 insertions(+), 44 deletions(-) diff --git a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodActivity.java b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodActivity.java index f195af509..26cc9154b 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodActivity.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodActivity.java @@ -21,7 +21,6 @@ import android.view.WindowManager; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import androidx.core.content.ContextCompat; @@ -42,8 +41,7 @@ public class AddTransferMethodActivity extends AppCompatActivity implements WidgetSelectionDialogFragment.WidgetSelectionItemListener, AddTransferMethodFragment.OnAddTransferMethodNetworkErrorCallback, AddTransferMethodFragment.OnLoadTransferMethodConfigurationFieldsNetworkErrorCallback, - OnNetworkErrorCallback, AddTransferMethodFragment.OnShowDateDialogCallback, - WidgetDateDialogFragment.OnSelectedDateCallback { + OnNetworkErrorCallback, WidgetDateDialogFragment.OnSelectedDateCallback { public static final String EXTRA_TRANSFER_METHOD_COUNTRY = "TRANSFER_METHOD_COUNTRY"; public static final String EXTRA_TRANSFER_METHOD_CURRENCY = "TRANSFER_METHOD_CURRENCY"; @@ -194,21 +192,6 @@ private AddTransferMethodFragment getAddTransferMethodFragment() { return fragment; } - @Override - public void showDateDialog(@Nullable final String date, @NonNull final String fieldName) { - FragmentManager fragmentManager = getSupportFragmentManager(); - WidgetDateDialogFragment fragment = (WidgetDateDialogFragment) - fragmentManager.findFragmentByTag(WidgetDateDialogFragment.TAG); - - if (fragment == null) { - fragment = WidgetDateDialogFragment.newInstance(date, fieldName); - } - - if (!fragment.isAdded()) { - fragment.show(fragmentManager); - } - } - @Override public void setSelectedDateField(@NonNull String fieldName, final String selectedValue) { FragmentManager fragmentManager = getSupportFragmentManager(); diff --git a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodFragment.java b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodFragment.java index a9691033c..b2caba7fe 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodFragment.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/transfermethod/AddTransferMethodFragment.java @@ -56,6 +56,7 @@ import com.hyperwallet.android.model.meta.field.HyperwalletFieldGroup; import com.hyperwallet.android.ui.HyperwalletLocalBroadcast; import com.hyperwallet.android.ui.repository.RepositoryFactory; +import com.hyperwallet.android.ui.view.WidgetDateDialogFragment; import com.hyperwallet.android.ui.view.WidgetSelectionDialogFragment; import com.hyperwallet.android.ui.view.widget.AbstractWidget; import com.hyperwallet.android.ui.view.widget.DateChangedListener; @@ -90,7 +91,6 @@ public class AddTransferMethodFragment extends Fragment implements WidgetEventLi private OnAddTransferMethodNetworkErrorCallback mOnAddTransferMethodNetworkErrorCallback; private OnLoadTransferMethodConfigurationFieldsNetworkErrorCallback mOnLoadTransferMethodConfigurationFieldsNetworkErrorCallback; - private OnShowDateDialogCallback mOnShowDateDialogCallback; private AddTransferMethodContract.Presenter mPresenter; private View mProgressBar; private boolean mShowCreateProgressBar; @@ -161,13 +161,6 @@ public void onAttach(Context context) { throw new ClassCastException(getActivity().toString() + " must implement " + OnLoadTransferMethodConfigurationFieldsNetworkErrorCallback.class.getCanonicalName()); } - - try { - mOnShowDateDialogCallback = (OnShowDateDialogCallback) context; - } catch (ClassCastException e) { - throw new ClassCastException(getActivity().toString() + " must implement " - + OnShowDateDialogCallback.class.getCanonicalName()); - } } @Override @@ -497,10 +490,6 @@ interface OnAddTransferMethodNetworkErrorCallback { void showErrorsAddTransferMethod(@NonNull final List errors); } - interface OnShowDateDialogCallback { - void showDateDialog(@Nullable final String date, @NonNull final String fieldName); - } - private void triggerSubmit() { if (performValidation(true)) { switch (mTransferMethodType) { @@ -599,7 +588,18 @@ public boolean isActive() { @Override public void openWidgetDateDialog(@Nullable final String date, @NonNull final String fieldName) { - mOnShowDateDialogCallback.showDateDialog(date, fieldName); + if (getFragmentManager() != null) { + WidgetDateDialogFragment dateDialogFragment = (WidgetDateDialogFragment) + getFragmentManager().findFragmentByTag(WidgetDateDialogFragment.TAG); + + if (dateDialogFragment == null) { + dateDialogFragment = WidgetDateDialogFragment.newInstance(date, fieldName); + } + + if (!dateDialogFragment.isAdded()) { + dateDialogFragment.show(getFragmentManager()); + } + } } void onDateSelected(@NonNull final String selectedValue, @NonNull final String fieldName) { diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/WidgetDateDialogFragment.java b/ui/src/main/java/com/hyperwallet/android/ui/view/WidgetDateDialogFragment.java index 6897467ef..0fd6910ff 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/view/WidgetDateDialogFragment.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/view/WidgetDateDialogFragment.java @@ -13,7 +13,6 @@ import androidx.fragment.app.FragmentManager; import com.hyperwallet.android.hyperwallet_ui.R; -import com.hyperwallet.android.ui.view.widget.DateParseException; import com.hyperwallet.android.ui.view.widget.DateUtil; import java.util.Calendar; @@ -24,7 +23,7 @@ public class WidgetDateDialogFragment extends DialogFragment { private static final String ARGUMENT_DATE = "ARGUMENT_DATE"; private static final String ARGUMENT_FIELD_NAME = "ARGUMENT_FIELD_NAME"; private OnSelectedDateCallback mOnSelectedDateCallback; - private DateUtil mDateUtil; + private final DateUtil mDateUtil = new DateUtil(); /** * Please do not use this to have instance of DateDialogFragment this is reserved for android framework @@ -76,8 +75,8 @@ public Dialog onCreateDialog(@Nullable Bundle state) { final String fieldName = getArguments().getString(ARGUMENT_FIELD_NAME); Calendar calendar; try { - calendar = getDateUtil().convertDateFromServerFormatToCalendar(storedDate); - } catch (DateParseException e) { + calendar = mDateUtil.convertDateFromServerFormatToCalendar(storedDate); + } catch (Exception e) { calendar = Calendar.getInstance(); } @@ -86,7 +85,7 @@ public Dialog onCreateDialog(@Nullable Bundle state) { new DatePickerDialog.OnDateSetListener() { @Override public void onDateSet(DatePicker view, int resultYear, int resultMonth, int resultDayOfMonth) { - final String selectedDate = getDateUtil() + final String selectedDate = mDateUtil .buildDateFromDateDialogToServerFormat(resultYear, resultMonth, resultDayOfMonth); mOnSelectedDateCallback.setSelectedDateField(fieldName, selectedDate); } @@ -104,16 +103,10 @@ public void onClick(DialogInterface dialog, int which) { } }); + datePickerDialog.setCanceledOnTouchOutside(false); return datePickerDialog; } - private DateUtil getDateUtil() { - if (mDateUtil == null) { - mDateUtil = new DateUtil(); - } - return mDateUtil; - } - public interface OnSelectedDateCallback { void setSelectedDateField(@NonNull final String fieldName, final String selectedValue); } diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateParseException.java b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateParseException.java index 1f951b5d5..207c9542d 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateParseException.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateParseException.java @@ -1,6 +1,6 @@ package com.hyperwallet.android.ui.view.widget; -public class DateParseException extends Exception { +class DateParseException extends Exception { public DateParseException(String message) { super(message); From ef1d1d0cf74b2e8edde9c54141c43a01924c0ac5 Mon Sep 17 00:00:00 2001 From: azakrevska-epam Date: Mon, 27 May 2019 16:36:47 +0300 Subject: [PATCH 8/8] HW-52174. Changed due to the review --- .../ui/view/widget/DateParseException.java | 16 ---- .../android/ui/view/widget/DateUtil.java | 40 ++------- .../android/ui/view/widget/DateWidget.java | 6 +- .../android/ui/view/widget/DateUtilTest.java | 82 ++++++------------- 4 files changed, 37 insertions(+), 107 deletions(-) delete mode 100644 ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateParseException.java diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateParseException.java b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateParseException.java deleted file mode 100644 index 207c9542d..000000000 --- a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateParseException.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.hyperwallet.android.ui.view.widget; - -class DateParseException extends Exception { - - public DateParseException(String message) { - super(message); - } - - public DateParseException(String message, Throwable cause) { - super(message, cause); - } - - public DateParseException(Throwable cause) { - super(cause); - } -} diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateUtil.java b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateUtil.java index 6e6c15d9b..8da501d0b 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateUtil.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateUtil.java @@ -26,7 +26,6 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; -import java.util.Date; import java.util.Locale; /** @@ -51,18 +50,13 @@ public DateUtil() { * * @param serverDate Date from server * @return String date in the format by BestDateTimePattern or dd MMMM yyyy otherwise - * @throws DateParseException unable to convert server date to widget format */ @NonNull - String convertDateFromServerToWidgetFormat(@Nullable final String serverDate) throws DateParseException { - try { - if (isServerDateValid(serverDate)) { - final Calendar calendar = Calendar.getInstance(); - calendar.setTime(mServerDateFormat.parse(serverDate)); - return mWidgetDateFormat.format(calendar.getTime()); - } - } catch (NumberFormatException | ParseException | IndexOutOfBoundsException e) { - throw new DateParseException("Unable to convert date from server to widget format", e.getCause()); + String convertDateFromServerToWidgetFormat(@Nullable final String serverDate) throws ParseException { + if (!TextUtils.isEmpty(serverDate)) { + final Calendar calendar = Calendar.getInstance(); + calendar.setTime(mServerDateFormat.parse(serverDate)); + return mWidgetDateFormat.format(calendar.getTime()); } return ""; } @@ -87,32 +81,14 @@ public String buildDateFromDateDialogToServerFormat(final int year, final int mo * * @param serverDate Date from server * @return Calendar with date from server - * @throws DateParseException unable to convert server date to calendar format */ @NonNull - public Calendar convertDateFromServerFormatToCalendar(@Nullable final String serverDate) throws DateParseException { + public Calendar convertDateFromServerFormatToCalendar(@Nullable final String serverDate) throws ParseException { final Calendar calendar = Calendar.getInstance(); - try { - if (isServerDateValid(serverDate)) { - calendar.setTime(mServerDateFormat.parse(serverDate)); - } - } catch (ParseException e) { - throw new DateParseException("Unable to convert server date to calendar format", e.getCause()); + if (!TextUtils.isEmpty(serverDate)) { + calendar.setTime(mServerDateFormat.parse(serverDate)); } return calendar; } - private boolean isServerDateValid(@Nullable final String serverDate) throws DateParseException { - Date date = null; - if (!TextUtils.isEmpty(serverDate)) { - SimpleDateFormat formatter = new SimpleDateFormat(SERVER_DATE_PATTERN, Locale.getDefault()); - formatter.setLenient(Boolean.FALSE); // make it strict - try { - date = formatter.parse(serverDate); - } catch (ParseException e) { - throw new DateParseException("Unable to parse server date to date format", e.getCause()); - } - } - return date != null; - } } \ No newline at end of file diff --git a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateWidget.java b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateWidget.java index b58e00a24..2a64a38d3 100644 --- a/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateWidget.java +++ b/ui/src/main/java/com/hyperwallet/android/ui/view/widget/DateWidget.java @@ -33,6 +33,8 @@ import com.hyperwallet.android.hyperwallet_ui.R; import com.hyperwallet.android.model.meta.field.HyperwalletField; +import java.text.ParseException; + public class DateWidget extends AbstractWidget implements DateChangedListener { private final DateUtil mDateUtil; @@ -67,7 +69,7 @@ public View getView(@NonNull final ViewGroup viewGroup) { try { mEditText.setText(mDateUtil.convertDateFromServerToWidgetFormat( TextUtils.isEmpty(mDefaultValue) ? mValue = mField.getValue() : mDefaultValue)); - } catch (DateParseException e) { + } catch (ParseException e) { mEditText.setText(""); } setIdFromFieldLabel(mTextInputLayout); @@ -115,7 +117,7 @@ public void onUpdate(@Nullable final String selectedDate) { mEditText.setText(mDateUtil.convertDateFromServerToWidgetFormat(selectedDate)); mListener.saveTextChanged(getName(), getValue()); mListener.valueChanged(); - } catch (DateParseException e) { + } catch (ParseException e) { mEditText.setText(selectedDate); } } diff --git a/ui/src/test/java/com/hyperwallet/android/ui/view/widget/DateUtilTest.java b/ui/src/test/java/com/hyperwallet/android/ui/view/widget/DateUtilTest.java index 801ce6851..d016de8af 100644 --- a/ui/src/test/java/com/hyperwallet/android/ui/view/widget/DateUtilTest.java +++ b/ui/src/test/java/com/hyperwallet/android/ui/view/widget/DateUtilTest.java @@ -3,63 +3,59 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; +import java.text.ParseException; import java.util.Arrays; import java.util.Calendar; import java.util.Collection; -import java.util.List; @RunWith(RobolectricTestRunner.class) public class DateUtilTest { private final DateUtil mDateUtil = new DateUtil(); + @Rule + public final ExpectedException mThrown = ExpectedException.none(); @Test - public void testParseIncorrectDateFromServerToWidget() throws Exception { - final List inputParamList = buildParamsDateFromServerToWidget(); - for (String serverDate : inputParamList) { - boolean isIncorrect = false; - try { - mDateUtil.convertDateFromServerToWidgetFormat(serverDate); - } catch (DateParseException e) { - isIncorrect = true; - } - assertThat(isIncorrect, is(true)); - } - } - - @Test - public void testParseCorrectDateFromServerToWidget() throws Exception { + public void testConvertDateFromServerToWidgetFormat() throws Exception { String serverDate = "2005-05-23"; String widgetDate = "23 May 2005"; assertThat(mDateUtil.convertDateFromServerToWidgetFormat(serverDate), is(widgetDate)); + } + + @Test + public void testBuildParamsDateFromServerToWidget_whenIncorrectDate() throws Exception { + mThrown.expect(ParseException.class); + mDateUtil.convertDateFromServerToWidgetFormat("1990-01"); + } + + @Test + public void testConvertDateFromServerToWidgetFormat_whenDateIsNullOrEmpty() throws Exception { assertThat(mDateUtil.convertDateFromServerToWidgetFormat(""), is("")); assertThat(mDateUtil.convertDateFromServerToWidgetFormat(null), is("")); } @Test - public void testParseIncorrectDateFromServerToCalendar() throws Exception { - List inputParamList = buildParamsDateFromServerToCalendar(); - for (String serverDate : inputParamList) { - boolean isIncorrect = false; - try { - mDateUtil.convertDateFromServerFormatToCalendar(serverDate).getTime(); - } catch (DateParseException e) { - isIncorrect = true; - } - assertThat(isIncorrect, is(true)); - } + public void testBuildParamsDateFromServerToCalendar_whenIncorrectDate() throws Exception { + mThrown.expect(ParseException.class); + mDateUtil.convertDateFromServerFormatToCalendar("123-32").getTime(); } @Test - public void testParseCorrectDateFromServerToCalendar() throws DateParseException { + public void testConvertDateFromServerFormatToCalendar_whenDateIsNullOrEmpty() throws ParseException { assertThat(mDateUtil.convertDateFromServerFormatToCalendar(null).getTime().toString(), is(Calendar.getInstance().getTime().toString())); assertThat(mDateUtil.convertDateFromServerFormatToCalendar("").getTime().toString(), is(Calendar.getInstance().getTime().toString())); + } + + @Test + public void testConvertDateFromServerFormatToCalendar() throws ParseException { String serverDate = "2005-05-23"; final Calendar mayCalendar = Calendar.getInstance(); mayCalendar.set(2005, 4, 23, 0, 0, 0); @@ -68,7 +64,7 @@ public void testParseCorrectDateFromServerToCalendar() throws DateParseException } @Test - public void testParseDateFromDialogToServerFormat() { + public void testBuildDateFromDateDialogToServerFormat() { String widgetDate; int year; int month; @@ -83,34 +79,6 @@ public void testParseDateFromDialogToServerFormat() { } } - private List buildParamsDateFromServerToWidget() { - return Arrays.asList( - "0", - "1990-01", - "1990-03-111", - "10-20-1", - "2190-13-1", - "2190-00-1", - "2190-01-00", - "2190-01-0", - "2190-01-32" - ); - } - - private List buildParamsDateFromServerToCalendar() { - return Arrays.asList( - "0", - "1990-01", - "1990-03-111", - "10-20-1", - "19-1102-1", - "2190-13-1", - "2190-00-1", - "2190-01-00", - "2190-01-0" - ); - } - private Collection buildParamsFromDialogToServer() { return Arrays.asList(new Object[][]{ {1900, 0, 1, "1900-01-01"},