diff --git a/androidshared/src/main/java/org/odk/collect/androidshared/ui/SnackbarUtils.kt b/androidshared/src/main/java/org/odk/collect/androidshared/ui/SnackbarUtils.kt index d68bc42885a..f228695874c 100644 --- a/androidshared/src/main/java/org/odk/collect/androidshared/ui/SnackbarUtils.kt +++ b/androidshared/src/main/java/org/odk/collect/androidshared/ui/SnackbarUtils.kt @@ -19,8 +19,10 @@ import android.widget.Button import android.widget.ImageView import android.widget.LinearLayout import android.widget.TextView +import androidx.lifecycle.Observer import com.google.android.material.snackbar.BaseTransientBottomBar import com.google.android.material.snackbar.Snackbar +import org.odk.collect.androidshared.data.Consumable /** * Convenience wrapper around Android's [Snackbar] API. @@ -40,6 +42,11 @@ object SnackbarUtils { return showSnackbar(parentView, message, 3500, anchorView, action, displayDismissButton) } + @JvmStatic + fun showLongSnackbar(parentView: View, snackbarDetails: SnackbarDetails) { + showLongSnackbar(parentView, snackbarDetails.text, action = snackbarDetails.action) + } + @JvmStatic @JvmOverloads fun showLongSnackbar( @@ -74,7 +81,8 @@ object SnackbarUtils { lastSnackbar?.dismiss() lastSnackbar = Snackbar.make(parentView, message.trim(), duration).apply { - val textView = view.findViewById(com.google.android.material.R.id.snackbar_text) + val textView = + view.findViewById(com.google.android.material.R.id.snackbar_text) textView.isSingleLine = false if (anchorView?.visibility != View.GONE) { @@ -88,7 +96,8 @@ object SnackbarUtils { setOnClickListener { dismiss() } - contentDescription = context.getString(org.odk.collect.strings.R.string.close_snackbar) + contentDescription = + context.getString(org.odk.collect.strings.R.string.close_snackbar) } val params = LinearLayout.LayoutParams( @@ -116,8 +125,23 @@ object SnackbarUtils { lastSnackbar?.show() } - data class Action( + data class SnackbarDetails @JvmOverloads constructor( val text: String, - val listener: () -> Unit + val action: Action? = null ) + + data class Action(val text: String, val listener: () -> Unit) + + abstract class SnackbarPresenterObserver(private val parentView: View) : + Observer> { + + abstract fun getSnackbarDetails(value: T): SnackbarDetails + + override fun onChanged(consumable: Consumable) { + if (!consumable.isConsumed()) { + showLongSnackbar(parentView, getSnackbarDetails(consumable.value)) + consumable.consume() + } + } + } } diff --git a/collect_app/src/main/java/org/odk/collect/android/activities/InstanceChooserList.java b/collect_app/src/main/java/org/odk/collect/android/activities/InstanceChooserList.java index fb993832836..4dac02a4cde 100644 --- a/collect_app/src/main/java/org/odk/collect/android/activities/InstanceChooserList.java +++ b/collect_app/src/main/java/org/odk/collect/android/activities/InstanceChooserList.java @@ -48,24 +48,21 @@ import org.odk.collect.android.external.FormUriActivity; import org.odk.collect.android.external.InstancesContract; import org.odk.collect.android.formlists.sorting.FormListSortingOption; -import org.odk.collect.android.formmanagement.FinalizeAllResult; import org.odk.collect.android.formmanagement.InstancesDataService; import org.odk.collect.android.formmanagement.drafts.BulkFinalizationViewModel; import org.odk.collect.android.formmanagement.drafts.DraftsMenuProvider; import org.odk.collect.android.injection.DaggerUtils; +import org.odk.collect.android.instancemanagement.FinalizeAllSnackbarPresenter; import org.odk.collect.android.projects.CurrentProjectProvider; import org.odk.collect.android.utilities.ApplicationConstants; import org.odk.collect.android.utilities.FormsRepositoryProvider; import org.odk.collect.android.utilities.InstancesRepositoryProvider; -import org.odk.collect.androidshared.ui.SnackbarUtils; import org.odk.collect.androidshared.ui.multiclicksafe.MultiClickGuard; import org.odk.collect.async.Scheduler; import org.odk.collect.forms.Form; import org.odk.collect.forms.instances.Instance; import org.odk.collect.material.MaterialProgressDialogFragment; import org.odk.collect.settings.SettingsProvider; -import org.odk.collect.strings.R.plurals; -import org.odk.collect.strings.R.string; import java.util.Arrays; @@ -161,45 +158,10 @@ public void onCreate(Bundle savedInstanceState) { return dialog; }); - bulkFinalizationViewModel.getFinalizedForms().observe(this, finalizedForms -> { - if (!finalizedForms.isConsumed()) { - FinalizeAllResult result = finalizedForms.getValue(); - if (result.getUnsupportedInstances()) { - SnackbarUtils.showLongSnackbar( - this.findViewById(android.R.id.content), - getResources().getString( - string.bulk_finalize_unsupported, - result.getSuccessCount() - ) - ); - } else if (result.getFailureCount() == 0) { - SnackbarUtils.showLongSnackbar( - this.findViewById(android.R.id.content), - getResources().getQuantityString( - plurals.bulk_finalize_success, - result.getSuccessCount(), - result.getSuccessCount() - ) - ); - } else if (result.getSuccessCount() == 0) { - SnackbarUtils.showLongSnackbar( - this.findViewById(android.R.id.content), - getResources().getQuantityString( - plurals.bulk_finalize_failure, - result.getFailureCount(), - result.getFailureCount() - ) - ); - } else { - SnackbarUtils.showLongSnackbar( - this.findViewById(android.R.id.content), - getString(string.bulk_finalize_partial_success, result.getSuccessCount(), result.getFailureCount()) - ); - } - - finalizedForms.consume(); - } - }); + bulkFinalizationViewModel.getFinalizedForms().observe( + this, + new FinalizeAllSnackbarPresenter(this.findViewById(android.R.id.content), this) + ); } private void init() { diff --git a/collect_app/src/main/java/org/odk/collect/android/instancemanagement/FinalizeAllSnackbarPresenter.java b/collect_app/src/main/java/org/odk/collect/android/instancemanagement/FinalizeAllSnackbarPresenter.java new file mode 100644 index 00000000000..c49863f1d32 --- /dev/null +++ b/collect_app/src/main/java/org/odk/collect/android/instancemanagement/FinalizeAllSnackbarPresenter.java @@ -0,0 +1,51 @@ +package org.odk.collect.android.instancemanagement; + +import android.content.Context; +import android.view.View; + +import androidx.annotation.NonNull; + +import org.odk.collect.android.formmanagement.FinalizeAllResult; +import org.odk.collect.androidshared.ui.SnackbarUtils; + +public class FinalizeAllSnackbarPresenter extends SnackbarUtils.SnackbarPresenterObserver { + private final Context context; + + public FinalizeAllSnackbarPresenter(@NonNull View parentView, Context context) { + super(parentView); + this.context = context; + } + + @NonNull + @Override + public SnackbarUtils.SnackbarDetails getSnackbarDetails(FinalizeAllResult result) { + if (result.getUnsupportedInstances()) { + return new SnackbarUtils.SnackbarDetails( + context.getString( + org.odk.collect.strings.R.string.bulk_finalize_unsupported, + result.getSuccessCount() + ) + ); + } else if (result.getFailureCount() == 0) { + return new SnackbarUtils.SnackbarDetails( + context.getResources().getQuantityString( + org.odk.collect.strings.R.plurals.bulk_finalize_success, + result.getSuccessCount(), + result.getSuccessCount() + ) + ); + } else if (result.getSuccessCount() == 0) { + return new SnackbarUtils.SnackbarDetails( + context.getResources().getQuantityString( + org.odk.collect.strings.R.plurals.bulk_finalize_failure, + result.getFailureCount(), + result.getFailureCount() + ) + ); + } else { + return new SnackbarUtils.SnackbarDetails( + context.getString(org.odk.collect.strings.R.string.bulk_finalize_partial_success, result.getSuccessCount(), result.getFailureCount()) + ); + } + } +}